關於的Java的i++和++i的區別,初學者可能會混淆,這時候有經驗的同學或同事就會告訴你,++在後,就會立馬加值,
++在後則會等會兒再加,所以如果i == 0 ,那麼i++ == 0,++i == 1。
那麼這個先加後加具體在字節碼中是怎樣一個邏輯呢?這個就需要我們去看看Java的字節碼了,如何查看字節碼請
參考我之前的文章IDEA設置External Tools之Javap反編譯字節碼。
準備兩個函數
函數test1
函數test2
先直接上函數的打印結果就,再來慢慢分析
先看test1的字節碼
0~3行:一次定義了i和j兩個變量,並賦值爲0,存放在局部變量表。
4~7行:開始循環的邏輯,if_icmpge是比較語句,如果j>=50則直接跳到第21行,調用打印方法。
核心的邏輯在10~15行:
現將局部變量表slot 0的變量加載到操作數棧,接着對局部變量表自增(沒錯,你沒看錯,這裏是對局部
變量表自增而不是對操作數棧的變量自增)。。緊接着下一步istore_0又把棧頂的值存回局部變量表slot_0,所以,。。
最終局部變量表的值是沒有改變的。
i++分析完畢,再回看上面的字節碼,其中還有值得注意的地方:
21~43行:這段對應代碼
1 System.out.println("i++: " + i);
先new一個PrintStream對象,下面可以看到是new了一個StringBuilder對象。這裏可能是jvm的一個優化,將字符串拼接
改成了StringBuilder來append,所以我們經常看到的有人說要把字符串拼接改成StringBuilder其實大可不必,先看下字節碼
對於語句的優化是怎樣的。
接着來看test2方法的字節碼:
前面的代碼和test1一樣,我們直接來看不一樣的地方:
該段字節碼對應代碼:
i = ++i;
先對局部變量表上的值自增,再加到操作數棧,最終存回到局部變量表,這樣的話變量表的值就是實實在在
增加了的。
所以,回想上面的分析,得出結論就是:i++是將變量表的值加載操作數棧後再對變量表上的值自增,而++i
則是先對變量表上的值自增後再將其加載到操作數棧。
當然,殊途同歸,最終不管是i++還是++i,都是爲了自增。
~~本文結束,感謝各位看官。