我認(rèn)為你并不理解i++和++i

你可能并不理解i++和++i.png

閱讀原文: 你可能并不理解i++和++i

面對i++和++i,是不是經(jīng)常忘記兩者的區(qū)別?你是真的理解它還是只是靠死記硬背記住的它?
如果你能以下面第一段的方式解釋它,那么可能還不是很理解 i++ ,若果要理解它需要你了解更多的知識。

public class Plus {
    public static void main(String args[]) {
        int num = 50;
        num = num++ * 2;
        System.out.println(num);
    }
}

1. 表面

num++ 是將原值先拿出來,自身再+1,此時num=51,然后將 50*2=100 再賦值給num,所以100覆蓋了原來的51。

這么回答是對的,大部分人可能都會這么回答,但你還能再深入點嗎?

2. JVM字節(jié)碼指令解讀

要理解這一層次,你需要先了解一下JVM的內(nèi)存結(jié)構(gòu)-虛擬機(jī)棧

2.1 虛擬機(jī)棧

我們應(yīng)該清楚 JVM 內(nèi)存中有如下幾個部分:


內(nèi)存模型

我們主要要了解虛擬機(jī)棧中運(yùn)算是如何進(jìn)行的,這里著重看局部變量表和操作數(shù)棧:

局部變量表:用于存放各種基本數(shù)據(jù)類型或?qū)ο笠?,就是方法?nèi)定義的局部變量,其存儲單元為slot槽(double/long占兩個slot,其他均占一個slot);JVM會為局部變量表中的每一個slot都分配一個訪問索引,通過這個索引即可成功訪問到局部變量表中指定的局部變量值。

局部變量表

操作數(shù)棧:這是一個棧的數(shù)據(jù)結(jié)構(gòu),可入棧彈出,將局部變量表中的變量放入棧中或彈出,CPU在計算時會從棧中取出并計算,然后計算結(jié)果再入棧。

操作數(shù)棧

2.2 字節(jié)碼指令

這里列出一些會用到的字節(jié)碼指令:

指令 意義
bipush 將單字節(jié)的常量值(-128~127)推送至棧頂
istore_n 將棧頂int型數(shù)值存入第n個本地變量
iload_n 將第n個int型本地變量推送至棧頂
Iinc 局部變量自增指令
iconst_n 將int型常量n推送至棧頂(n<=5)
imul 將棧頂兩int型數(shù)值相乘并將結(jié)果壓入棧頂

在IDEA中安裝bytecode插件,點擊 view -> show bytecode 將上面的程序轉(zhuǎn)為字節(jié)碼指令來看看他是如何做的:

L0

 //將50推送至棧頂
 BIPUSH 50
 
 //將50取出存儲到第一個變量中
 ISTORE 1
 
L1
 
 //將第一個變量中50推送至棧頂
 ILOAD 1
 
 //將第一個變量進(jìn)行加1操作,此時局部變量num=51
 IINC 1 1
 
 //將常量2推送至棧頂,此時棧中有兩個數(shù)50,2
 ICONST_2
 
 //將棧中的數(shù)進(jìn)行相乘,然后放入棧頂 50*2 = 100
 IMUL
   
 //取出棧頂元素100存入第一個變量中,num = 100
 ISTORE 1

如果你之前沒有了解過字節(jié)碼相關(guān)的東西,那么你看上面可能有些吃力,所以我制作了動畫給你看(善良不?):

動畫解析:

step1.gif
step2.gif
step3.gif

更善良的是:如果你想要上面動畫的源文件,公眾號回復(fù) “ i++ ” 即可。

2.3 擴(kuò)展

如果將上面代碼中的 num++ 替換成 ++num 結(jié)果會怎么呢?

這兩者的不同在于 ILOAD 1IINC 1 1 的順序,是先將變量放入操作數(shù)棧中再將變量加1 還是 先將變量加1再將變量放入操作數(shù)棧中。

往期文章一覽

故事:走進(jìn)JVM的世界(圖文并茂)Java

千萬不要這樣使用 Arrays.asList !

集合去重三境界

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容