2 回答
TA贡献1809条经验 获得超8个赞
请参阅 JVM 规范,§2.11.1。类型和 Java 虚拟机:
请注意,表 2.11.1-A中的大多数指令没有整数类型
byte
、char
和 的形式short
。没有一个具有该boolean
类型的形式。编译器对大量类型的文字值进行编码byte
,并使用 Java 虚拟机指令在编译时或运行时short
将这些值符号扩展为类型值。int
加载类型的文字值boolean
并使用在编译时或运行时char
将文字零扩展为类型值的指令进行编码。int
同样,从boolean
、 、byte
、short
和类型的值数组加载char
,使用 Java 虚拟机指令进行编码,这些指令将值符号扩展或零扩展为类型值int
. 因此,大多数对实际类型boolean
、byte
、char
和的值的操作short
都由对计算类型 的值进行操作的指令正确执行int
。
值得回顾的是,在 Java 中,任何不涉及的整数算术long
都会有int
结果,无论输入是byte
、char
、short
、 或int
。
所以一行像
short i = 1, j = 2, k = i + j;
不会编译,但需要类型转换,比如
short i = 1, j = 2, k = (short)(i + j);
这种类型转换将是唯一short
涉及的指示器。撇开调试提示不谈,字节码中没有局部变量的正式声明,只有确定其类型的值赋值。所以类型的局部变量short
根本不存在。上面的代码编译为
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: i2s
8: istore_3
这与编译形式相同
int i = 1, j = 2, k = (short)(i + j);
但请注意,变量的编译时类型可以更改编译器在重载时选择调用的方法。print(boolean)如果类型具有不同的语义(例如or的情况),这一点尤其重要print(char)。虽然传递给该方法的值int在这两种情况下都有类型,但结果却完全不同。
编译器强制执行的差异的另一个示例是
{
int i = 1;
i++;
}
{
short s = 1;
s++;
}
其被编译为
0: iconst_1
1: istore_1
2: iinc 1, 1
5: iconst_1
6: istore_1
7: iload_1
8: iconst_1
9: iadd
10: i2s
11: istore_1
因此,由于计算始终以 32 位执行,因此编译器插入必要的代码以将结果截断为short第二次递增。再次注意没有变量声明,因此代码与编译后的形式相同
int i = 1;
i++;
i = 1;
i = (short)(i+1);
验证类型系统也值得一看,因为验证者将检查所有从局部变量到局部变量的传输的有效性:
类型检查器基于验证类型的层次结构强制执行类型系统,如下所示。
Verification type hierarchy: top ____________/\____________ / \ / \ oneWord twoWord / | \ / \ / | \ / \ int float reference long double / \ / \_____________ / \ / \ uninitialized +------------------+ / \ | Java reference | / \ | type hierarchy | uninitializedThis uninitialized(Offset) +------------------+ | | null
因此,与 Java 语言类型相比,类型系统得到了简化,并且验证器不会介意,例如,如果您将值传递boolean
给需要 a 的方法char
,因为两者都是int
类型。
添加回答
举报