我想这是一个基本的问题,但是为什么没有卸载指令呢?为什么你可以加载所有的原语,除了短?(有沙拉,但还是.)
适用于:
public class ShortTest {
public void test() {
short i = 1;
System.out.print(i);
}
}编译器仍然使用iload_1。因为short是16位类型,处理器处理更好的32位(因为所有现代处理器都是32/64位)吗?
发布于 2019-08-27 16:03:19
参考JVM规范,第2.11.1节。类型与Java虚拟机
请注意,表2.11.1-A中的大多数指令都没有完整类型
byte、char和short的表单。没有一个具有boolean类型的窗体。编译器使用Java指令对byte和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)或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);同样值得研究的是验证式系统,因为验证器将检查所有从局部变量到局部变量的传输的有效性:
类型检查器基于验证类型的层次结构强制执行类型系统,如下所示。 验证类型层次结构:顶_/\\ oneWordtwoWord / int浮点数引用长双//\/ \____________/\/未初始化+不初始化(偏移)+-+
因此,与Java语言类型相比,类型系统是简化的,验证器并不介意,例如,如果您将boolean值传递给期望char的方法,这两种类型都是int类型。
发布于 2019-08-27 11:31:14
因为所有局部变量至少占用一个32位的插槽。同样的事情也适用于字节。
https://stackoverflow.com/questions/57673666
复制相似问题