程序目的
從java字節碼層理解,為何i = i++后,結果是+1之前的數值。而i=++i后,結果是+1之后的值。
關鍵指令
iload_<n>:
從局部變量表獲取值,并壓入操作數棧。
istore_<n>:
出棧,然后存儲到局部變量表。
i++示例源碼
public class TestIPulsPlus { public static void main(String[] args) { int i = 8; i = i++; // i = ++i; System.out.println(i); } }
i++執行結果:
8
使用jclasslib查看i++字節碼
找到main方法的Code區:
圖:i=i++字節碼
字節碼解讀
0 bipush 8
把數值8壓入操作數棧,壓棧前轉為int類型。
2 istore_1
8出棧,存到編號為1的局部變量表。
圖:編號為1的局部變量為1
以上兩行指令,完成了int i = 8;
這行代碼。
3 iload_1
從局部變量表,獲取int值8。然后壓到操作數棧。
4 iinc 1 by 1
把局部變量表中的i,進行+1操作。此時棧里面數值是8,局部變量表中i為9。
7 istore_1
8出棧,存到編號為1的局部變量表。也就是賦值給i變量。局部變量表的i值從9變為8。
接下來,解讀i=++i的字節碼
圖:i=++i;字節碼
++i示例源碼
public class TestIPulsPlus { public static void main(String[] args) { int i = 8; // i = i++; i = ++i; System.out.println(i); } }
執行結果為:
9
i=++i字節碼解讀
0 bipush 8
把數值8壓入操作數棧,壓棧前轉為int類型。
2 istore_1
8出棧,存到編號為1的局部變量表。
圖:編號為1的局部變量為1
以上兩行指令,完成了int i = 8;這行代碼。
3 iinc 1 by 1
把局部變量表中的i,進行+1操作。此時,局部變量表中i為9。
6 iload_1
從局部變量表,獲取int值9。然后壓到操作數棧。
7 istore_1
9出棧,存到編號為1的局部變量表。也就是賦值給i變量。
參考
Chapter 6. The Java Virtual Machine Instruction Set
總結
i=i++
和i=++i
,第3、4行位置是相反的。
i++
是先執行iload_1
,再執行iinc 1 by 1。
iload_1:
從局部變量表,獲取int值8。然后壓到操作數棧。
iinc 1 by 1
:把局部變量表中的i,進行+1操作。此時棧里面數值是8,局部變量表中i為9。
istore_1
時,獲取的是棧中的8,所以最后結果為8。
而++i
,是先執行iinc 1 by 1
,再執行iload_1
。
iinc 1 by 1
: 把局部變量表中的i,進行+1操作。此時,局部變量表中i為9。
iload_1
:從局部變量表,獲取int值9。然后壓到操作數棧。
istore_1
時,獲取的是棧中的9,所以最后結果為9。
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!
原文鏈接:https://blog.csdn.net/limenghua9112/article/details/120415912