Java的i = i++与i=++i的去呗从JVM指令讲解图文并茂,一文必懂

一、Java的i = i++深入JVM指令讲解 图文并茂 看了必懂

先看一段简单的代码

package com.zhou.jvm.runtimedataAreainstructionset;

/**
 * @author zhouyanxiang
 * @create 2020-08-2020/8/5-19:55
 */
public class TestPlusPlus {
    public static void main(String[] args) {
        int i = 8;
        i = i++;
        System.out.println(i);
    }
}

最后程序打印的结果是8不是9

那么这个是为什么呢?我们从JVM指令来看

编译这个类之后我们用jclasslib插件show bytecode with jclasslib,可以看到如下

我把里面的Bytecode单独拿出来,粘在这里

 0 bipush 8
 2 istore_1
 3 iload_1
 4 iinc 1 by 1
 7 istore_1
 8 getstatic #2 <java/lang/System.out>
11 iload_1
12 invokevirtual #3 <java/io/PrintStream.println>
15 return

接下来一条一条指令的解析

1. bipush 8

第一步,bipush指令具体的含义就是把一个int类型的数据压入操作数栈。具体的可以参照官网链接,如下图所示把8压入了操作数栈

2. istore_1

第二步,istore_1就是将操作数栈的数字弹出栈并写入局部变量表当中建立的一个index值为1的索引的变量,这里程序的i变量此时就为8,完成了int i = 8的操作。

3. iload_1

第三步,iload_1指令就是将局部变量表中的值再次压入操作数栈当中去。所以此时操作数栈里面的值此时为8

4. iinc 1 by 1

第四步,iinc 1 by 1就是将局部变量表中索引值为1的变量加一,就是完成了i++这一步操作,此时局部变量表中的i为9

4

5. istore_1

第五步,istore_1就是将操作数栈的数字弹出栈并写入局部变量表当中建立的一个index值为1的索引的变量,这里程序的i变量此时就为8,完成了int i = i++的操作。

6. iload_1

因此最后输出的就是8

二、换成i=++i的JVM指令研究

package com.zhou.jvm.runtimedataAreainstructionset;

/**
 * @author zhouyanxiang
 * @create 2020-08-2020/8/5-19:55
 */
public class TestPlusPlus {
    public static void main(String[] args) {
        int i = 8;
        i = ++i;
        System.out.println(i);
    }
}

这个类的Bytecode

i=++i的bytecode

 0 bipush 8
 2 istore_1
 3 iinc 1 by 1
 6 iload_1
 7 istore_1
 8 getstatic #2 <java/lang/System.out>
11 iload_1
12 invokevirtual #3 <java/io/PrintStream.println>
15 return

把i = i++的bytecode拿出来对比

 0 bipush 8
 2 istore_1
 3 iload_1
 4 iinc 1 by 1
 7 istore_1
 8 getstatic #2 <java/lang/System.out>
11 iload_1
12 invokevirtual #3 <java/io/PrintStream.println>
15 return

可以看出两者之间的区别在于 iload_1 和 iinc 1 by 1的顺序问题

i=++i的是先 iinc 1 by 1再 iload_1,就是说先对局部变量表的变量进行自增再把这个自增以后的值压入操作数栈,自然这个操作数栈的数据已经+1了

i=i++的是先iload_1 再iinc 1 by 1,就是说先把局部变量表中的变量的值压入操作数栈,再进行自增操作,所以这个对于后续的istore_1操作有影响,使得这个最终的局部变量表中的数据还是之前没有加1的那个数值。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值