<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 1817字,需瀏覽 4分鐘

           ·

          2020-06-26 23:25

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

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

          1. 表面

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

          這么回答是對(duì)的,大部分人可能都會(huì)這么回答,但你還能再深入點(diǎn)嗎?

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

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

          2.1 虛擬機(jī)棧

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


          58514246480b0d2026921afee7742fa7.webp


          內(nèi)存模型

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

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

          3c938853801245578304bd62f1b8076f.webp

          局部變量表

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

          3f43d7e94f0704fcda5fa4074a4fb750.webp

          操作數(shù)棧

          2.2 字節(jié)碼指令

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

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

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

          L0

          //將50推送至棧頂
          BIPUSH 50

          //將50取出存儲(chǔ)到第一個(gè)變量中
          ISTORE 1

          L1

          //將第一個(gè)變量中50推送至棧頂
          ILOAD 1

          //將第一個(gè)變量進(jìn)行加1操作,此時(shí)局部變量num=51
          IINC 1 1

          //將常量2推送至棧頂,此時(shí)棧中有兩個(gè)數(shù)50,2
          ICONST_2

          //將棧中的數(shù)進(jìn)行相乘,然后放入棧頂 50*2 = 100
          IMUL

          //取出棧頂元素100存入第一個(gè)變量中,num = 100
          ISTORE 1

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

          動(dòng)畫解析:

          251f5cf8bd27afaa649f239596e591bd.webp

          step1

          26c28f210a514eac0ede0b44fe683325.webp

          step2

          b8d541efe37e03f8790d08d11442850d.webp

          step3

          更善良的是59570bf935f5541543a83a208ed3b8df.webp:如果你想要上面動(dòng)畫的源文件,公眾號(hào)回復(fù) “ i++ ” 即可。

          2.3 擴(kuò)展

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

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

          瀏覽 73
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色电影网站免费 | 私人女仆扫地偷懒被主人颜色吃现在被喷尿洗脸 | 香蕉一区二区三区四区 | 色婷婷做视频网站 | 无码三区四区电影院 |