i++和++i的区别底层是如何实现的?(Java)

入门理解

i++:先操作再自增

++i:先自增再操作

这个理解一般是没毛病的,但是如果遇到下面这个问题,这个理解就不够用了

问题

int i=0;
i=i++;
System.out.println("i="+i);//问题:i=?
int j=0;
j=++j;
System.out.println("j="+j);//问题:j=?

大家可以自己试着运行一下,这里公布答案:

i=0
j=1

问题答案解析

需要事先知道的知识

局部变量表:可以理解为真正存放变量值的地方.操作变量时需要把表中变量读到操作数栈中操作

操作数栈:是进行运算的地方.可想而知,操作数栈中操作的变量最后要刷新到局部变量表中

先说问题答案解析后的结论

i++是把i的值放到操作数栈中运算,然后局部变量表中值+1,

++i是把i先在局部变量表中+1,再把加了的新i值放到操作数栈中去运算

结论是如何得到的

这里我拿到了代码对应编译后的字节码文件

对于int i=0; i=i++;

//初始化阶段int i=0
iconst_0        // 将常量0压入操作数栈(栈顶=0)
istore_1        // 将栈顶的0存入局部变量表位置1(i=0)

// 执行 i=i++
iload_1         // 重点是这里,i++是在改变局部变量表数据之前值0加载到操作数栈(栈顶=0)
iinc 1, 1       // 直接在局部变量表中将i自增1(i=1)
istore_1        // 将操作数栈顶的旧值0存回i(覆盖自增结果,i=0)

重点看这两行代码注释:

iload_1 // 重点是这里,i++是在改变局部变量表数据之前值0加载到操作数栈(栈顶=0)
iinc 1, 1 // 直接在局部变量表中将i自增1(i=1)

i最后等于0也容易知道原因了**,因为操作树栈中的结果是i=0,最后操作完成后刷新到局部变量表的新结果i=0会覆盖旧的i自增后的i=1**

对于int j=0; j=++j;

// 初始化阶段
iconst_0        // 将常量0压入操作数栈(栈顶=0)
istore_2        // 将栈顶的0存入局部变量表位置2(j=0)

// 执行 j=++j
iinc 2, 1       // 直接在局部变量表中将j自增1(j=1)
iload_2         // 重点在这里,++j是局部变量表+1之后将值1加载到操作数栈(栈顶=1)
istore_2        // 将栈顶的1存回j(j=1)

重点:

iinc 2, 1 // 直接在局部变量表中将j自增1(j=1)
iload_2 // 重点在这里,++j是局部变量表+1之后将值1加载到操作数栈(栈顶=1)

这里也明白了为什么最后j=1,因为操作数栈中操作的结果是j=1,最后刷新到局部变量表的也是j=1

再来总结一下结论

可以明白了,其实i++和++i在字节码这个层面的区别很简单,就两行字节码指令顺序不一样而已.

所以我总结了一下更深入的口诀


i++:先放到操作数栈操作,再在局部变量表中自增

++i:现在局部变量表中自增,再放到操作数栈中操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值