本文涉及的主要字节码指令:
iconst_0/istore_1/iload_1/iinc
iconst_0:入栈指令,将数字0压入操作数栈。
istore_1:弹出栈顶元素,存入位置1的局部变量中。
iload_1:从位置为1的局部变量中取出元素int类型的值入栈。
iinc:局部变量自增指令。
首先i = i++;和i = ++i;的计算结果是不同的,观察下面两段代码:
int i = 0;
i = i++;
System.out.println(i);//输出0
int i = 0;
i = ++i;
System.out.println(i);//输出1
查看两段代码生成的字节码:
//i = i++;
Code:
stack=2, locals=2, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
14: return
//i = ++i;
Code:
stack=2, locals=2, args_size=1
0: iconst_0
1: istore_1
2: iinc 1, 1
5: iload_1
6: istore_1
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
14: return
字节码执行过程示意图:
字节码执行过程
赋值操作是将操作数栈中的值赋值给变量,由于iinc指令直接更新局部变量表,导致i=i++;执行过程中首先将0放入操作数栈,然后局部变量自增,最后将操作数栈中的0回写到局部变量表,导致变量被覆盖回0。
网友评论