<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-07-11 11:31

          面對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)-虛擬機棧

          2.1 虛擬機棧

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


          d55bfa031890377a20e214dbe108d4da.webp


          內(nèi)存模型

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

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

          f333268ca0db8338d1d82feb96df2b64.webp

          局部變量表

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

          4a963ad4085a72da28ad5ad99f7c0729.webp

          操作數(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

          //將第一個變量進行加1操作,此時局部變量num=51
          IINC 1 1

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

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

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

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

          動畫解析:

          8747bc37890cc5d60c5bc608741a3165.webp

          step1

          96eb9b6cff3326fed9bea91fd37f7a4e.webp

          step2

          b42f236be4a4374c19e011f41ed8ffa9.webp

          step3

          更善良的是17ee4e9313b7380f438a07655e36c077.webp:如果你想要上面動畫的源文件,公眾號回復 “ i++ ” 即可。

          2.3 擴展

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

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

          瀏覽 19
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  学生妹A级片 | 操逼麻豆| 啊啊嗯嗯视频 | 水蜜桃一区二区三区 | 日本精品视频网站 |