從 JVM 層面理解 i++ 和 ++i 的真正區(qū)別!
前言
如果只用普通的知識(shí)解釋i++和++i的話
i++ 先將i賦值再++ ++i 先++再賦值
但是這簡(jiǎn)單的回答并不能入吸引面試官的眼球,如果用java字節(jié)碼指令分析則效果完全不同。
代碼實(shí)現(xiàn)
public class OperandStackTest {
/**
程序員面試過(guò)程中, 常見(jiàn)的i++和++i 的區(qū)別
*/
public static void add(){
//第1類問(wèn)題:
int i1 = 10;
i1++;
System.out.println(i1);//11
int i2 = 10;
++i2;
System.out.println(i2);//11
//第2類問(wèn)題:
int i3 = 10;
int i4 = i3++;
System.out.println(i3);//11
System.out.println(i4);//10
int i5 = 10;
int i6 = ++i5;
System.out.println(i5);//11
System.out.println(i6);//11
//第3類問(wèn)題:
int i7 = 10;
i7 = i7++;
System.out.println(i7);//10
int i8 = 10;
i8 = ++i8;
System.out.println(i8);//11
//第4類問(wèn)題:
int i9 = 10;
int i10 = i9++ + ++i9;//10+12
System.out.println(i9);//12
System.out.println(i10);//22
}
public static void main(String[] args) {
add();
}
}

字節(jié)碼指令
通過(guò)javap -v out目錄下的class文件名 在終端運(yùn)行得到如下結(jié)果
public static void add();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=10, args_size=0
0: bipush 10
2: istore_0
3: iinc 0, 1
6: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
9: iload_0
10: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
13: bipush 10
15: istore_1
16: iinc 1, 1
19: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
22: iload_1
23: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
26: bipush 10
28: istore_2
29: iload_2
30: iinc 2, 1
33: istore_3
34: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
37: iload_2
38: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
41: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
44: iload_3
45: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
48: bipush 10
50: istore 4
52: iinc 4, 1
55: iload 4
57: istore 5
59: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
62: iload 4
64: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
67: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
70: iload 5
72: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
75: bipush 10
77: istore 6
79: iload 6
81: iinc 6, 1
84: istore 6
86: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
89: iload 6
91: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
94: bipush 10
96: istore 7
98: iinc 7, 1
101: iload 7
103: istore 7
105: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
108: iload 7
110: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
113: bipush 10
115: istore 8
117: iload 8
119: iinc 8, 1
122: iinc 8, 1
125: iload 8
127: iadd
128: istore 9
130: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
133: iload 8
135: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
138: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
141: iload 9
143: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
146: return
解釋以上運(yùn)行結(jié)果
第一類問(wèn)題

對(duì)應(yīng)的指令為

先將i1的值為10入棧(bipush),然后將int類型的值從棧中存到局部變量表0的位置,然后執(zhí)行iinc將0位置的值+1,然后將局部變量表0位置的數(shù)入棧執(zhí)行輸出操作
所以i1的值為11
先將i2的值為10入棧(bipush),然后將int類型的值從棧中存到局部變量表1的位置,然后執(zhí)行iinc將1位置的值+1,然后將局部變量表1位置的數(shù)入棧執(zhí)行輸出操作
所以i2的值為11
總結(jié)
由于沒(méi)有賦值操作,區(qū)別不大。
第二類問(wèn)題


所以i3是11,i4還是10
將i5入棧存儲(chǔ)到局部變量表4的位置,由于是++i所以先iinc將4位置的值加一,然后將局部變量表4的值入棧,執(zhí)行賦值操作,所以都是11。另外,Java 系列面試題和答案全部整理好了,微信搜索互聯(lián)網(wǎng)架構(gòu)師,在后臺(tái)發(fā)送:2T,可以在線閱讀。
第三類問(wèn)題


先將i7入棧,然后存到局部變量表6的位置,先把i6入棧,然后把6處的值加一,由于又將這個(gè)值存儲(chǔ)到局部變量表6處,所以產(chǎn)生覆蓋又把值變?yōu)?0。
第四類問(wèn)題

int i10 = i9++ + ++i9;此時(shí)i9=10+1+1為12,然后將8位置的i9入棧,執(zhí)行add將棧中的兩i9相加,得到的值存儲(chǔ)到局部變量表9的位置
所以i10=10+12(i9++后還是10,++i9后是12,因?yàn)閳?zhí)行了兩次iinc操作)
然后調(diào)用虛方法和靜態(tài)方法,在將9處的值入棧執(zhí)行輸出語(yǔ)句。
原文鏈接:https://blog.csdn.net/demo_yo/article/details/118269423
感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!小編到你上高速。
正文結(jié)束
1.不認(rèn)命,從10年流水線工人,到谷歌上班的程序媛,一位湖南妹子的勵(lì)志故事
3.從零開(kāi)始搭建創(chuàng)業(yè)公司后臺(tái)技術(shù)棧
5.37歲程序員被裁,120天沒(méi)找到工作,無(wú)奈去小公司,結(jié)果懵了...
6.IntelliJ IDEA 2019.3 首個(gè)最新訪問(wèn)版本發(fā)布,新特性搶先看
一個(gè)人學(xué)習(xí)、工作很迷茫?
點(diǎn)擊「閱讀原文」加入我們的小圈子!

