这里我尝试编译java文件,我使用java反编译器来检查已编译的代码。为什么char被转换为int并且一些变量名也改变了?
class CharacterTest{
public static void main(String[] args){
char t=140;
char f='t';
char p='t';
System.out.print(t);
}
}
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 :(得分:2)
JVM和字节码本身不区分char和int。这只是在语义/语言层面。
第二个局部变量名不包含在类文件中。因此反编译器必须发明自己的名字。
答案 1 :(得分:1)
完全取决于反编译器的实现细节。反编译器不知道局部变量的名称和类型,因此必须使用一些启发式方法从字节码重构它。
您的字节码如下所示:
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()
签名作为提示来确定t
的类型)和变量名称的生成取决于类型(c
的{{1}},char
的{{1}}和i
的{{1}}。
另见:
答案 2 :(得分:0)
char实际上是Integer类型。
char类型(一个字符)包含一个16位Unicode字符,实际上由无符号的16位整数表示。
(来源:Kathy Sierra的SCJP)
关于命名更改,我不确定。但我想这是你的反编译器的一个问题。您是否尝试过不同的反编译器并查看每个人都生成的变量名称?
答案 3 :(得分:0)
如上所述,VM的局部变量只能包含类型(或更确切地说,可以通过命令访问)int
,long
,float
,{{1} }和引用 - 所以所有整数类型(除了long)都在内部被视为double
。
第一个变量仍为int
,因为这是此处调用的char
方法的参数类型,因此编译器有一些方法可以猜测它,而其他两个变量不再使用,所以他们留在println()
。