最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談JVM 底層解析 i++和 ++i 區(qū)別

 更新時(shí)間:2021年09月09日 11:07:31   作者:默默無(wú)聞代碼人  
這篇文章主要介紹了JVM 底層解析 i++和 ++i 區(qū)別,需要的朋友可以參考下面文章的具體內(nèi)容

一、前言

如果只用普通的知識(shí)解釋i++和++i的話
i++ 先將i賦值再++
++i 先++再賦值
但是這簡(jiǎn)單的回答并不能入吸引面試官的眼球,如果用java字節(jié)碼指令分析則效果完全不同

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

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

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

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

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

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

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

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

    public static void main(String[] args) {
        add();
    }
}

運(yùn)行結(jié)果

i1 = 11
i2 = 11
i3 = 11
i4 = 10
i5 = 11
i6 = 11
i7 = 10
i8 = 11
i9 = 12
i10 = 22

三、字節(jié)碼指令

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

四、字節(jié)碼解析

1. 第一類問題

 //第1類問題:
 int i1 = 10;
 i1++;
 System.out.println("i1 =" + i1);//11

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

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

   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

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

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

2. 第二類問題

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

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

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

  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

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

所以i3是11,i4還是10

將i5入棧存儲(chǔ)到局部變量表4的位置,由于是++i所以先iinc將4位置的值加一,然后將局部變量表4的值入棧,執(zhí)行賦值操作

所以i5、i6都是11

3. 第三類問題

 //第3類問題:
 int i7 = 10;
 i7 = i7++;
 System.out.println("i7 =" + i7);//10
 int i8 = 10;
 i8 = ++i8;
 System.out.println("i8 =" + i8);//11

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

  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

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

所以i7為10

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

所以i8為11

4. 第四類問題

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

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

 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

先將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ǔ)句

到此這篇關(guān)于淺談JVM 底層解析 i++和 ++i 區(qū)別的文章就介紹到這了,更多相關(guān)JVM 底層解析 i++和 ++i 區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring-Boot 訪問外部接口的方案總結(jié)

    Spring-Boot 訪問外部接口的方案總結(jié)

    在Spring-Boot項(xiàng)目開發(fā)中,存在著本模塊的代碼需要訪問外面模塊接口,或外部url鏈接的需求,針對(duì)這一需求目前存在著三種解決方案,下面將對(duì)這三種方案進(jìn)行整理和說明,對(duì)Spring-Boot 訪問外部接口方案感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • 基于RocketMQ推拉模式詳解

    基于RocketMQ推拉模式詳解

    這篇文章主要介紹了RocketMQ推拉模式的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring Boot CORS 配置方法允許跨域請(qǐng)求的最佳實(shí)踐方案

    Spring Boot CORS 配置方法允許跨域請(qǐng)求的最佳實(shí)踐方案

    跨域請(qǐng)求在現(xiàn)代Web開發(fā)中非常重要,特別是在涉及多個(gè)前端和后端服務(wù)時(shí),本文詳細(xì)介紹了跨域請(qǐng)求的背景、重要性以及如何解決跨域問題,通過SpringBoot框架的CORS配置,可以有效地處理跨域請(qǐng)求,確保數(shù)據(jù)傳輸?shù)陌踩院陀脩趔w驗(yàn),感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Spring boot 打jar包分離lib的正確配置方式

    Spring boot 打jar包分離lib的正確配置方式

    spring boot打jar包分離lib后,配置文件的方式,在網(wǎng)上可以搜到很多答案,但是都不夠完善,今天小編給大家?guī)砹薙pring boot 打jar包分離lib的正確配置方式,感興趣的朋友一起看看吧
    2018-02-02
  • Springboot RocketMq實(shí)現(xiàn)過程詳解

    Springboot RocketMq實(shí)現(xiàn)過程詳解

    這篇文章主要介紹了Springboot RocketMq實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Java后臺(tái)基于POST獲取JSON格式數(shù)據(jù)

    Java后臺(tái)基于POST獲取JSON格式數(shù)據(jù)

    這篇文章主要介紹了Java后臺(tái)基于POST獲取JSON格式數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • springboot責(zé)任鏈模式實(shí)現(xiàn)多級(jí)校驗(yàn)

    springboot責(zé)任鏈模式實(shí)現(xiàn)多級(jí)校驗(yàn)

    責(zé)任鏈模式是將鏈中的每一個(gè)節(jié)點(diǎn)看作是一個(gè)對(duì)象,每個(gè)節(jié)點(diǎn)處理的請(qǐng)求不同,且內(nèi)部自動(dòng)維護(hù)一個(gè)下一節(jié)點(diǎn)對(duì)象,下面我們來聊聊springboot如何利用責(zé)任鏈模式實(shí)現(xiàn)多級(jí)校驗(yàn)吧
    2024-11-11
  • Java實(shí)現(xiàn)定時(shí)任務(wù)最簡(jiǎn)單的3種方法

    Java實(shí)現(xiàn)定時(shí)任務(wù)最簡(jiǎn)單的3種方法

    幾乎在所有的項(xiàng)目中,定時(shí)任務(wù)的使用都是不可或缺的,如果使用不當(dāng)甚至?xí)斐少Y損,下面這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)定時(shí)任務(wù)最簡(jiǎn)單的3種方法,本文通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Springboot文件上傳功能的實(shí)現(xiàn)

    Springboot文件上傳功能的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot文件上傳功能的實(shí)現(xiàn),文中通過代碼示例介紹的非常詳細(xì),具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們可以參考閱讀
    2023-04-04
  • Java幾個(gè)實(shí)例帶你進(jìn)階升華下篇

    Java幾個(gè)實(shí)例帶你進(jìn)階升華下篇

    與其明天開始,不如現(xiàn)在行動(dòng),本文為你帶來幾個(gè)Java書寫的實(shí)際案例,對(duì)鞏固編程的基礎(chǔ)能力很有幫助,快來一起往下看看吧
    2022-03-03

最新評(píng)論

大竹县| 南宁市| 巴彦淖尔市| 拉萨市| 彭泽县| 商城县| 尼玛县| 乐清市| 沅江市| 和顺县| 正镶白旗| 日土县| 大化| 建宁县| 如皋市| 错那县| 东莞市| 平度市| 呼伦贝尔市| 顺昌县| 阳曲县| 会东县| 昌图县| 内江市| 彭泽县| 富锦市| 太康县| 巴青县| 郯城县| 北京市| 佳木斯市| 固原市| 济南市| 宜川县| 通榆县| 沈丘县| 葵青区| 濉溪县| 沾益县| 江城| 荆门市|