次のプログラムのバイトコードを見てみましょう。
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_2
andが実行されます。1 つはそれをロードするためのもので、もう 1 つは 2 番目のオペランドとしてのものです。その後、( ) にロードするが実行されます。4: dup
2
a
5: istore_1
2
a
a = 2
最後に、6: iadd
第1 オペランドと第 2 オペランドを加算して結果をスタックにプッシュし、結果をポップして にロードする7: istore_1
場所で実行されます。6: iadd
7: istore_1
a
簡単にするために、このコードを簡単に見てみましょう。
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
ます。