<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>

          從 JVM 層面理解 i++ 和 ++i 的真正區(qū)別!

          共 13849字,需瀏覽 28分鐘

           ·

          2021-09-12 15:36

          上一篇:深夜看了張一鳴的微博,讓我越想越后怕

          前言

          如果只用普通的知識(shí)解釋i++和++i的話

          • i++ 先將i賦值再++
          • ++i 先++再賦值

          但是這簡(jiǎn)單的回答并不能入吸引面試官的眼球,如果用java字節(jié)碼指令分析則效果完全不同。

          代碼實(shí)現(xiàn)

          public class OperandStackTest {
          /**
              程序員面試過(guò)程中, 常見(jiàn)的i++和++i 的區(qū)別
               */
              public static void add(){
                  //第1類問(wèn)題:
                  int i1 = 10;
                  i1++;
                  System.out.println(i1);//11

                  int i2 = 10;
                  ++i2;
                  System.out.println(i2);//11

                  //第2類問(wèn)題:
                  int i3 = 10;
                  int i4 = i3++;
                  System.out.println(i3);//11
                  System.out.println(i4);//10

                  int i5 = 10;
                  int i6 = ++i5;
                  System.out.println(i5);//11
                  System.out.println(i6);//11

                  //第3類問(wèn)題:
                  int i7 = 10;
                  i7 = i7++;
                  System.out.println(i7);//10

                  int i8 = 10;
                  i8 = ++i8;
                  System.out.println(i8);//11

                  //第4類問(wèn)題:
                  int i9 = 10;
                  int i10 = i9++ + ++i9;//10+12
                  System.out.println(i9);//12
                  System.out.println(i10);//22
              }

              public static void main(String[] args) {
                  add();
              }
          }
          運(yùn)行結(jié)果

          字節(jié)碼指令

          通過(guò)javap -v out目錄下的class文件名 在終端運(yùn)行得到如下結(jié)果

           public static void add();
              descriptor: ()V
              flags: ACC_PUBLIC, ACC_STATIC
              Code:
                stack=2, locals=10, args_size=0
                   0: bipush        10
                   2: istore_0
                   3: iinc          0, 1
                   6: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                   9: iload_0
                  10: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                  13: bipush        10
                  15: istore_1
                  16: iinc          1, 1
                  19: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                  22: iload_1
                  23: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                  26: bipush        10
                  28: istore_2
                  29: iload_2
                  30: iinc          2, 1
                  33: istore_3
                  34: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                  37: iload_2
                  38: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                  41: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                  44: iload_3
                  45: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                  48: bipush        10
                  50: istore        4
                  52: iinc          4, 1
                  55: iload         4
                  57: istore        5
                  59: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                  62: iload         4
                  64: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                  67: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                  70: iload         5
                  72: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                  75: bipush        10
                  77: istore        6
                  79: iload         6
                  81: iinc          6, 1
                  84: istore        6
                  86: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                  89: iload         6
                  91: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                  94: bipush        10
                  96: istore        7
                  98: iinc          7, 1
                 101: iload         7
                 103: istore        7
                 105: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                 108: iload         7
                 110: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                 113: bipush        10
                 115: istore        8
                 117: iload         8
                 119: iinc          8, 1
                 122: iinc          8, 1
                 125: iload         8
                 127: iadd
                 128: istore        9
                 130: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                 133: iload         8
                 135: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                 138: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
                 141: iload         9
                 143: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
                 146: return

          解釋以上運(yùn)行結(jié)果

          第一類問(wèn)題

          對(duì)應(yīng)的指令為

          先將i1的值為10入棧(bipush),然后將int類型的值從棧中存到局部變量表0的位置,然后執(zhí)行iinc將0位置的值+1,然后將局部變量表0位置的數(shù)入棧執(zhí)行輸出操作

          所以i1的值為11

          先將i2的值為10入棧(bipush),然后將int類型的值從棧中存到局部變量表1的位置,然后執(zhí)行iinc將1位置的值+1,然后將局部變量表1位置的數(shù)入棧執(zhí)行輸出操作

          所以i2的值為11

          總結(jié)

          由于沒(méi)有賦值操作,區(qū)別不大。

          第二類問(wèn)題


          先將i3入棧存儲(chǔ)到局部變量表2的位置,然后將它入棧,執(zhí)行iinc將2位置的值加一,i4存儲(chǔ)到局部表量表3的位置


          所以i3是11,i4還是10

          將i5入棧存儲(chǔ)到局部變量表4的位置,由于是++i所以先iinc將4位置的值加一,然后將局部變量表4的值入棧,執(zhí)行賦值操作,所以都是11。另外,Java 系列面試題和答案全部整理好了,微信搜索互聯(lián)網(wǎng)架構(gòu)師,在后臺(tái)發(fā)送:2T,可以在線閱讀。

          第三類問(wèn)題

          對(duì)應(yīng)字節(jié)碼

          先將i7入棧,然后存到局部變量表6的位置,先把i6入棧,然后把6處的值加一,由于又將這個(gè)值存儲(chǔ)到局部變量表6處,所以產(chǎn)生覆蓋又把值變?yōu)?0。

          而++i不會(huì)產(chǎn)生覆蓋先執(zhí)行加一然后再把值入棧,在賦值給局部變量表中,所以i8為11。

          第四類問(wèn)題

          先將i9=10入棧,然后存在局部變量表8的位置
          int i10 = i9++ + ++i9;
          先iload將8位置的i9入棧然后執(zhí)行iinc將8處的i9加一,然后執(zhí)行++i9,在將8處的i9加一

          此時(shí)i9=10+1+1為12,然后將8位置的i9入棧,執(zhí)行add將棧中的兩i9相加,得到的值存儲(chǔ)到局部變量表9的位置

          所以i10=10+12(i9++后還是10,++i9后是12,因?yàn)閳?zhí)行了兩次iinc操作)

          然后調(diào)用虛方法和靜態(tài)方法,在將9處的值入棧執(zhí)行輸出語(yǔ)句。

          原文鏈接:https://blog.csdn.net/demo_yo/article/details/118269423

          感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!小編到你上高速。

              · END ·
          最后,關(guān)注公眾號(hào)互聯(lián)網(wǎng)架構(gòu)師,在后臺(tái)回復(fù):2T,可以獲取我整理的 Java 系列面試題和答案,非常齊全。


          正文結(jié)束


          推薦閱讀 ↓↓↓

          1.不認(rèn)命,從10年流水線工人,到谷歌上班的程序媛,一位湖南妹子的勵(lì)志故事

          2.如何才能成為優(yōu)秀的架構(gòu)師?

          3.從零開(kāi)始搭建創(chuàng)業(yè)公司后臺(tái)技術(shù)棧

          4.程序員一般可以從什么平臺(tái)接私活?

          5.37歲程序員被裁,120天沒(méi)找到工作,無(wú)奈去小公司,結(jié)果懵了...

          6.IntelliJ IDEA 2019.3 首個(gè)最新訪問(wèn)版本發(fā)布,新特性搶先看

          7.這封“領(lǐng)導(dǎo)痛批95后下屬”的郵件,句句扎心!

          8.15張圖看懂瞎忙和高效的區(qū)別!

          一個(gè)人學(xué)習(xí)、工作很迷茫?


          點(diǎn)擊「閱讀原文」加入我們的小圈子!

          瀏覽 48
          點(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>
                  天堂网在线观看 | 中国女人一级片 | 国产精品秘 久久久久久奇米影视 | 亚洲天堂无码aV | 91乱子伦国产乱子伦www.sz-sd.cn |