Java字节代码对此和堆栈上的参数进行排序

Jon*_*ans 7 java parameters stack jvm bytecode

在java字节码中,为什么接收器首先被压入堆栈,然后是所有参数?我似乎记得它与效率有关.

对于方法调用和设置字段都是如此.

方法调用

class X {

    int p(int a) {
        //Do something
    }
    int main() {
        int ret = p(1);
    }

}
Run Code Online (Sandbox Code Playgroud)

主要方法编译为:

aload_0 // Load this onto the stack
iconst_1 // Load constant 1 onto the stack
invokevirtual <int p(int)> from class X
Run Code Online (Sandbox Code Playgroud)

设置字段:

class X {
    int x;
    int main() {
        x = 1;
    }

}
Run Code Online (Sandbox Code Playgroud)

主要方法编译为:

aload_0 // Load this onto the stack
iconst_1 // Load constant 1 onto the stack
putfield <int x> from class X
Run Code Online (Sandbox Code Playgroud)

Tre*_*ald 1

首先被推动的优势在于

  • 目标方法可以使用更密集的“aload0”字节码(比它在参数列表中更晚并且必须使用 aload 字节码的参数版本要小。因为“this”经常在字段和方法访问的方法中引用,它会带来真正的代码密度提高。
  • 人们经常使用级联方法发送,例如“foo.bar().baz()”。当 bar() 返回时,如果您按照 Java 中的方式进行安排,则 .baz() 的未来“this”神奇地已经位于堆栈上的正确位置。