我们看一下下面程序的字节码:
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 方法中的两行:
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
- 从本地
variable 1 加载一个 int 值并将其压入堆栈。
-------------
| | 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) 的第一个操作数并压入堆栈。
接下来,3: iconst_2 和 4: dup 被执行,它们基本上将 int 2 两次压入堆栈;一个用于将其加载到a,另一个作为第二个操作数。之后,5: istore_1 被执行,将2 加载到a (a = 2)。
最后,6: iadd 和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。