java - 为什么在 JVM 中 Integer 存储为 byte 和 short?

标签 java jvm

这是一段代码

public class Classifier {
    public static void main(String[] args) 
    {
        Integer x = -127;//this uses bipush
        Integer y = 127;//this use bipush
        Integer z= -129;//this use sipush
        Integer p=32767;//maximum range of short still sipush
        Integer a = 128; // use sipush
        Integer b = 129786;// invokes virtual method to get Integer class

    }

}

这是部分字节码

      stack=1, locals=7, args_size=1
         0: bipush        -127
         2: invokestatic  #16                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
         5: astore_1
         6: bipush        127
         8: invokestatic  #16                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
        11: astore_2
        12: sipush        -129
        15: invokestatic  #16                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
        18: astore_3
        19: sipush        32767
        22: invokestatic  #16                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
        25: astore        4
        27: sipush        128
        30: invokestatic  #16                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
        33: astore        5
        35: ldc           #22                 // int 129786
        37: invokestatic  #16                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
        40: astore        6
        42: return

正如我看到的,对于 -128 到 127 之间的整数范围,它使用 bipush 将一个字节作为整数值压入堆栈。 在 -32768 到 32767 范围内,它使用 short 作为 sipush 的包装类。接下来它使用整数。什么 JVM 使用 byte 和 short 来存储 Integer 值?

最佳答案

它在运行时不存储为byteshort,只是在字节码中。 假设您要将值 120 存储到 Integer 中。您编写了编译器,因此您解析了源代码,并且您知道常量值 120 可以放入一个带符号的字节中。因为您不想在字节码中浪费空间来将值 120 存储为 32 位(4 字节)值,如果它可以存储为 8 位(1 字节),您将创建特殊指令,即将只能从方法字节码加载一个 byte 并将其作为 32 位 integer 存储在堆栈中。这意味着,在运行时,您确实拥有 integer 数据类型。

与在任何地方使用 ldc 相比,生成的代码更小更快,后者需要与 jvm 进行更多交互,因为需要使用运行时常量池进行操作。

bipush 有 2 个字节,一个字节操作码,第二个字节立即常量值。因为您只有一个字节用于值,所以它可用于 -128 到 127 之间的值。

sipush有3个字节,一个字节的操作码,第二个和第三个字节立即数 常数值。

bipush 格式:

bipush
byte

sipush格式:

sipush
byte1
byte2

关于java - 为什么在 JVM 中 Integer 存储为 byte 和 short?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29875430/

相关文章:

Java 无法从 AIX 解析 DNS 地址 : UnknownHostException

java - 仅用于在页面上搜索的 Eclipse 快捷方式

java - 重载泛型方法时 Java 5 和 6 之间的不同行为

java - Java 方法可以有超过 255 个局部变量吗?

c# - 从 C++/Java/C# 代码调用 C 方法?

java - 带有 JSP 的 JDBC 无法插入

java - 我的 jar 可以在 Ubuntu 上运行,但不能在 Windows 上运行

java - 从 VisualVM 理解堆图

java - 带有静态方法的抽象类。那是对的吗?

java - Java .class 文件的最大大小是多少?