详细分析jvm中i++与++i背后的指令

第1类问题

public void addTest1() {
    //第1类问题
    int i1 = 10;
    i1++;
    int i2 = 10;
    ++i2;
    /**
     * 对应的指令
     *  0 bipush 10         10入栈
     *  2 istore_1          栈顶存入slot1,此时i1=10
     *  3 iinc 1 by 1       slot1加1,此时i1=11
     *  6 bipush 10         10入栈
     *  8 istore_2          栈顶存入slot2,此时i2=10
     *  9 iinc 2 by 1       slot2加1,此时i2=11
     * 12 return
     */
}

第2类问题

public void addTest2() {
    //第2类问题
    int i3 = 10;
    int i4 = i3++;
    int i5 = 10;
    int i6 = ++i5;
    /**
     * 代码对应的指令
     *  0 bipush 10         向操作数数栈推入10
     *  2 istore_1          将栈顶数存入局部变量表槽位1的位置,即i3=10
     *  3 iload_1           将i3压入栈顶
     *  4 iinc 1 by 1       iinc表示对局部变量表索引1的位置加1(by 1),也就是i3加1,此时i3=11
     *  iinc应该是一个简化的指令,实际上是slot入栈,栈顶自加,栈顶出栈三条指令的合集,因为4之后
     *  直接就是7了,正好隔了3个
     *  7 istore_2          将栈顶的10存入slot2中,也就是i4=10
     *  8 bipush 10         10入栈
     * 10 istore_3          栈顶元素存入slot3,也就是i5=10
     * 11 iinc 3 by 1       slot3中元素加1,此时i5=11
     * 14 iload_3           slot3中元素入栈
     * 15 istore 4          栈顶元素存入slot4,即i6=11
     * 17 return            返回
     */
}

第3类问题

public void addTest3() {
    //第3类问题
    int i7 = 10;
    i7 = i7++;
    int i8 = 10;
    i8 = ++i8;
    /**
     * 代码对应的指令
     *  0 bipush 10         10放入栈顶
     *  2 istore_1          栈顶存入slot1,即i7=10
     *  3 iload_1           slot1入栈,此时栈顶为10
     *  4 iinc 1 by 1       i7(局部变量表中slot1)自加1,此时i7=11
     *  7 istore_1          栈顶(10)存入slot1,也就是i7又变回了10
     *
     *  8 bipush 10         10放到栈顶
     * 10 istore_2          栈顶元素存入slot2
     * 11 iinc 2 by 1       slot2自加1变为11
     * 14 iload_2           slot2入栈
     * 15 istore_2          栈存入slot2,此时slot2为11,即i8为11
     * 16 return
     */
}

第4类问题

public void addTest4() {
    //第4类问题
    int i9 = 10;
    int i10 = i9++ + ++ i9;
    System.out.println(i9);
    System.out.println(i10);
    /**
     * 对应的指令
     *  0 bipush 10         10入栈
     *  2 istore_1          栈顶(10)存入slot1(i9=10)
     *  3 iload_1           slot1入栈(10)
     *  4 iinc 1 by 1       slot1加1(11)
     *  7 iinc 1 by 1       slot1加1(12),i9=12
     * 10 iload_1           slot1入栈(12)
     * 11 iadd              10+12=22
     * 12 istore_2          栈顶到slot2,此时i10=22.
     * 13 return
     */
}

总结
虽然不用分析指令,也能够得出正确的结果,但是遇到第3类、第4类问题的时候可能就不那么确信自己的答案了。这里分析了一下指令,心里踏实多了。总的来说自加是在局部变量表上操作的,具体实现可能还是用到了操作数栈,但是这里就我们表面上看到的就是直接在slot上进行的操作,只要不是后来被重新覆盖掉原值,不管是++i,还是i++,结果最终都是i增加了1。但是像第3类问题,因为有一个赋值操作,相当于使用栈中的值把slot中的值给覆盖了,所以会造成结果的不一致现象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值