博客详情

JVM中i++和++i (原创)

作者: 朝如青丝暮成雪
发布时间:2020-09-13 19:12:27  文章分类:JVM   阅读(834)  评论(0)

如下java代码最后输出的a、b的值分别是多少


public class Demo3_2 {

    public static void main(String[] args) {
        int a=10;
        int b = a++ +  ++a  + a--;
        System.out.println(a);//?
        System.out.println(b);//?
    }
}

我们用javap反编译工具查看下类的字节码.

javap  -v Demo3_2.class  其中main方法的字节码指令树下:

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: bipush        10
         2: istore_1
         3: iload_1
         4: iinc          1, 1
         7: iinc          1, 1
        10: iload_1
        11: iadd
        12: iload_1
        13: iinc          1, -1
        16: iadd
        17: istore_2
        18: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        21: iload_1
        22: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        25: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        28: iload_2
        29: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        32: return
      LineNumberTable:
        line 32: 0
        line 33: 3
        line 34: 18
        line 35: 25
        line 36: 32
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      33     0  args   [Ljava/lang/String;
            3      30     1     a   I
           18      15     2     b   I


stack=2 表示栈桢中操作数栈的最大深度为2,locals=3表示局部变量表有3个槽位。槽位0是args ,也就是main方法的入参,槽位1和2分别对应局部变量a和b

我们来分析下,这段源码生成的字节码指令:


bipush 10  执行引擎读取到该指令,将数字10压入操作数栈

istore_1    执行引擎将操作数栈中的值弹出,放入到局部变量表1号槽位,此时1号槽位的值为10

iload_1     执行引擎将局部变量表1号槽位的值压入操作数栈,此时操作数栈中存放的第一个值为10

iinc 1,1     执行引擎将局部变量表1号槽位变量值加1,此时1号槽位的值变为11

iinc 1,1     执行引擎局部变量表1号槽位变量值加1,此时1号槽位的值变为12

iload_1     执行引擎将局部变量表1号槽位的值压入操作数栈,此时操作数栈中存放的第二个值为12

iadd         执行引擎执行将操作数栈的两个数字相加得到22【10+12】,此时操作数栈中只留下一个值22

iload_1     执行引擎将局部变量表1号槽位的值压入操作数栈,此时操作数栈中存放的第二个值为12

iinc 1,-1   执行引擎局部变量表1号槽位变量值减1,此时1号槽位的值变为11

iadd         执行引擎将操作数栈的两个数字相加得到34【22+12】,此时操作数栈中只留下一个值34

istore_2   执行引擎将操作数栈中值弹出,放入局部变量表2号槽位,此时2号槽位的值为34

...


因此,最终的结果是:a的值为11,b的值为34


经过分析,我们发现了 i++和++i 在字节码层面上的不同:

i++ :   先执行iload (将局部变量表slot中的变量压入操作数栈) ,再执行iinc 1,1(局部变量表slot槽中变量自加1)

++i :   先执行iinc 1,1(局部变量表slot槽中变量自加1) ,再执行iload (将局部变量表slot中的变量压入操作数栈) 



关键字:  jvm  字节码
评论信息
暂无评论
发表评论

亲,您还没有登陆,暂不能评论哦! 去 登陆 | 注册

博主信息
   
数据加载中,请稍候...
文章分类
   
数据加载中,请稍候...
阅读排行
 
数据加载中,请稍候...
评论排行
 
数据加载中,请稍候...

Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1

鄂公网安备 42011102000739号