为了账号安全,请及时绑定邮箱和手机立即绑定

JVM指令-sload

JVM指令-sload

慕运维8079593 2023-06-21 13:35:36
我想这是一个基本问题,但为什么没有sload指令?为什么可以加载除 short 之外的所有图元?(有saload,但仍然......)为了 :public class ShortTest {    public void test() {        short i = 1;        System.out.print(i);    }}编译器仍然使用iload_1。是因为 Short 是 16 位类型,而处理器可以更好地处理 32 位(因为所有现代处理器都是 32/64 位)?
查看完整描述

2 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

请参阅 JVM 规范,§2.11.1。类型和 Java 虚拟机:

请注意,表 2.11.1-A中的大多数指令没有整数类型bytechar和 的形式short。没有一个具有该boolean类型的形式。编译器对大量类型的文字值进行编码byte,并使用 Java 虚拟机指令在编译时或运行时short将这些值符号扩展为类型值。int加载类型的文字值boolean并使用在编译时或运行时char将文字零扩展为类型值的指令进行编码。int同样,从boolean、 、byteshort和类型的值数组加载char,使用 Java 虚拟机指令进行编码,这些指令将值符号扩展或零扩展为类型值int. 因此,大多数对实际类型booleanbytechar和的值的操作short都由对计算类型 的值进行操作的指令正确执行int

值得回顾的是,在 Java 中,任何不涉及的整数算术long都会有int结果,无论输入是bytecharshort、 或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类型。


查看完整回答
反对 回复 2023-06-21
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

因为所有局部变量都至少占用一个32位槽。字节也是如此。



查看完整回答
反对 回复 2023-06-21
  • 2 回答
  • 0 关注
  • 96 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信