Java 为什么原始代码和编译代码之间存在差异

Java 为什么原始代码和编译代码之间存在差异,java,decompiling,Java,Decompiling,在这里,我试图编译java文件,并使用java反编译器检查编译后的代码。为什么将char转换为int,并且一些变量名也发生了更改 原始JAVA文件 编译代码 char实际上是一种整数类型 字符类型(字符)包含单个16位Unicode字符,实际上由无符号16位整数表示 (资料来源:凯西·塞拉的SCJP) 关于名字的改变,我不确定。但我想这是你的反编译程序的问题。您是否尝试过不同的反编译器并看到了每个人生成的变量名?这完全取决于反编译器的实现细节。反编译器不知道局部变量的名称和类型,所以它必须使用一

在这里,我试图编译java文件,并使用java反编译器检查编译后的代码。为什么将char转换为int,并且一些变量名也发生了更改

原始JAVA文件 编译代码
char实际上是一种整数类型

字符类型(字符)包含单个16位Unicode字符,实际上由无符号16位整数表示

(资料来源:凯西·塞拉的SCJP)


关于名字的改变,我不确定。但我想这是你的反编译程序的问题。您是否尝试过不同的反编译器并看到了每个人生成的变量名?

这完全取决于反编译器的实现细节。反编译器不知道局部变量的名称和类型,所以它必须使用一些启发式方法从字节码中重建它

您的字节码如下所示:

0: sipush 140 3: istore_1 4: bipush 116 6: istore_2 7: bipush 116 9: istore_3 0:sipush 140 3:istore_1 4:bipush 116 6:istore_2 7:bipush 116 9:istore_3 如您所见,
140
被视为
short
类型的常量,而
116
被视为
byte
类型的常量(这是因为
116
适合有符号字节,但
140
不适合)

现在反编译器试图猜测它在源代码中的含义。反编译器似乎将常量类型的差异视为局部变量类型的差异(也可以使用编译器选择的
print()
choosen的签名作为提示来确定
t
的类型),并且根据类型生成变量名(
c
用于
char
i
j
用于
int

另请参见:


JVM和字节码本身并不区分char和int。这只是在语义/语言级别上


类文件中不包含第二个局部变量名。因此,反编译器必须发明自己的名称。

如前所述,VM的局部变量只能具有类型(或者更准确地说,可以使用命令访问)
int
long
float
double
和reference-因此所有整数类型(除了long)在内部都被视为
int


第一个变量仍然是
char
,因为这是
println()的参数类型
方法在这里调用,因此编译器有办法猜测它,而其他两个变量不再使用,因此它们留在这里。

char为什么char t=140;没有更改为intok。在这种情况下,关于变量的更改,请留下,但您能对char更改为int给出更多解释吗?@setheesh:没有更改。Decompiler不知道局部变量的类型,并试图从字节码猜出它。
import java.io.PrintStream;

class CharacterTest
{
public static void main(String[] paramArrayOfString)
{
char c = '';
int i = 116;
int j = 116;
System.out.print(c);
}
}
0: sipush 140 3: istore_1 4: bipush 116 6: istore_2 7: bipush 116 9: istore_3