首页 > 解决方案 > Java 字节码 - 为什么要跳过偏移量?

问题描述

我有这个非常简单的课程

public class TestImpl2 {
    public TestImpl2() {
    }

    public double run(double param) {
        double d = 7.0D;
        double k = 4.0D;
        if (param < k) {
            System.out.println(d);
        }

        return 0.0D;
    }
}

我用 javac 编译然后用 javap 反编译以查看它的字节码。

     0: ldc2_w        #14                 // double 7.0d
     3: dstore_3
     4: ldc2_w        #16                 // double 4.0d
     7: dstore        5
     9: dload_1
    10: dload         5
    12: dcmpg
    13: ifge          23
    16: getstatic     #23                 // Field java/lang/System.out:Ljava/io/PrintStream;
    19: dload_3
    20: invokevirtual #29                 // Method java/io/PrintStream.println:(D)V
    23: dconst_0
    24: dreturn

让我们检查偏移量

0 - 为“this”引用保留

1 - 是方法参数

2 - 跳过?

3 - 变量“d”

4 - 跳过?

5 - 变量“k”

为什么跳过了偏移量 2 和 4?是因为方法参数、d 和 k 是双精度数还是完全不同?

标签: javabytecode

解决方案


根据JVM规范(强调我的):

局部变量通过索引来寻址。第一个局部变量的索引为零。当且仅当该整数比局部变量数组的大小小 0 到 1 之间时,整数才被认为是局部变量数组的索引。

typelong或 type的值double占用两个连续的局部变量。这样的值只能使用较小的索引来解决。例如,存储在索引 n 处的局部变量数组中的 double 类型的值实际上占用了索引为 n 和 n+1 的局部变量;但是,不能从中加载索引 n+1 处的局部变量。

并不是不使用索引 2 和 4。就是这样,param并且ddoubles,它们每个占据 2 个空间。


推荐阅读