從字節碼層次看i++和++i

  

  關於的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,都是爲了自增。

 

  ~~本文結束,感謝各位看官。

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章