7

Javaバイトコードでは、レシーバーが最初にスタックにプッシュされ、その後にすべてのパラメーターがプッシュされるのはなぜですか? 効率と関係があることを覚えているようです。

これは、メソッド呼び出しと設定フィールドの両方に当てはまります。

メソッド呼び出し

class X {

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

}

Main メソッドは次のようにコンパイルされます。

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

フィールドの設定:

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

}

Main メソッドは次のようにコンパイルされます。

aload_0 // Load this onto the stack
iconst_1 // Load constant 1 onto the stack
putfield <int x> from class X
4

2 に答える 2

1

最初にプッシュされることには、次のような利点があります。

  • ターゲット メソッドは、より密度の高い「aload0」バイトコードを使用できます (パラメーター リストのずっと後ろにあり、aload バイトコードのパラメトリック バージョンを使用する必要がある場合よりも小さいです。「this」は、フィールド アクセスとメソッド アクセスの両方のメソッドで参照されることが多いためです)。 、実際のコード密度の向上につながります。
  • 「foo.bar().baz()」のようにカスケードメソッド送信を行うことがよくあります。bar() が返されたとき、Java で行われたように配置すると、.baz() の将来の「this」は魔法のようにスタックの適切な場所に既に配置されています。
于 2012-05-29T04:40:07.640 に答える
1

なぜプッシュされたのかと尋ねていますか?どちらの場合も、クラスのインスタンスに属するものにアクセスしているためthis、そのプロセスの一部である必要があります。

なぜそれが最初にプッシュされるのか尋ねていますか?ただのJava規約。this後に続く可能性のある多くのことに関係なく、常に最初に持っていると便利だと思います。

于 2012-05-12T21:42:16.170 に答える