次のプログラムのバイトコードを見てみましょう。
package A;
public class Test
{
public static void main(String[] args)
{
int a = 1;
a += (a = 2);
}
}
次のコマンドを実行するだけです。
javap -c Test.class
次のバイトコードを取得します。
public class A.Test {
public A.Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: istore_1
2: iload_1
3: iconst_2
4: dup
5: istore_1
6: iadd
7: istore_1
8: return
}
説明:
main メソッド内の 2 行だけに注目します。
int a = 1;
a += (a = 2);
【int a = 1;ここから始まる】
0: iconst_1
-------------
| |
-------------
| |
-------------
| 1 |
-------------
STACK
1: istore_1
- スタックから int 値を
variable 1(variable 1を表すa)にポップします。
-------------
| | variable 1
------------- --------------
| | | 1 |
------------- --------------
| |
-------------
STACK
【int a = 1;ここまでです】
【a += (a = 2);ここから始まる】
2: iload_1
- ローカルから int 値をロード
variable 1し、スタックにプッシュします。
-------------
| | variable 1
------------- --------------
| | | |
------------- --------------
| 1 |
-------------
STACK
3: iconst_2
-------------
| | variable 1
------------- --------------
| 2 | | |
------------- --------------
| 1 |
-------------
STACK
4: dup
-------------
| 2 | variable 1
------------- --------------
| 2 | | |
------------- --------------
| 1 |
-------------
STACK
5: istore_1
- int 値をスタックから にポップします
variable 1。
-------------
| | variable 1
------------- --------------
| 2 | | 2 |
------------- --------------
| 1 |
-------------
STACK
6: iadd
-------------
| | variable 1
------------- --------------
| | | 2 |
------------- --------------
| 3 |
-------------
STACK
7: istore_1
- int 値をスタックから にポップします
variable 1。
-------------
| | variable 1
------------- --------------
| | | 3 |
------------- --------------
| |
-------------
STACK
【a += (a = 2);ここまでです】
8: return
結論:
a = a + (a = 2)いくつかの操作によって行われます。式の最初のオペランドを読み取り、スタックにプッシュする2: iload_1最初のコマンドとして実行されます。a += (a = 2);a = a + (a = 2)
次に、基本的に intを 2 回スタックにプッシュする3: iconst_2andが実行されます。1 つはそれをロードするためのもので、もう 1 つは 2 番目のオペランドとしてのものです。その後、( ) にロードするが実行されます。4: dup2a5: istore_12aa = 2
最後に、6: iadd第1 オペランドと第 2 オペランドを加算して結果をスタックにプッシュし、結果をポップして にロードする7: istore_1場所で実行されます。6: iadd7: istore_1a
簡単にするために、このコードを簡単に見てみましょう。
int a = 1;
int b = 3;
a += b;
バイトコードは次のとおりです。
public class A.Test {
public A.Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: istore_1
2: iconst_3
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_1
8: return
}
ご覧のとおり、次のことを行うだけです。
- にint
1をロードしaます。
- にint
3をロードしbます。
aその後、スタックにプッシュbします。
- それらに対して加算を実行し、結果をスタックにプッシュします。
- スタックから結果をポップし、 に格納し
aます。