从底层搞定i++ 和++i的区别

先看示例1

上面的示例中结果为8

示例2

结果为9

要说明上面两个示例结果,我们首先的前提是需要了解:一.jvm的运行时数据区(栈,堆,程序计数器,方法区(1.8以后称为元数据区,1.8以前称为永久代),本地方法区),这里我们只针对栈来说明,栈包括:1.局部变量表(local Variable) 2.操作数栈 (Operand Stack) 3.Dynamic Linking 4.return Adresss(相当于在a方法中调用b方法,当b执行完时,b方法返回值放的位置)

问题模糊点:需要分清楚操作数栈和局部变量表不是同一个东西

二.jclasslib插件(自行百度)

现在开始说明上面的问题

 

 

上图是i=i++的执行过程,红框中的是jvm的指令集。下面一句一句解释指令集

bipush 8:将8 压入操作数栈

istore_1:将栈顶的数8从操作数栈取出放入局部变量表位置1中(现在int i=8完成,局部变量表中的i的值为8)

iload_1: 将局部变量表中位置1的数据8取出放入操作数栈中(现在操作数栈中的数为8)

inic 1 by 1:将局部变量表中的位置为1的值加1(现在局部变量表中i的值为9)

istore_1:将操作数栈取出位置1的数也就是8放入局部变量表位置1中(局部变量表中的i的值重新赋为8)

getstatic #2:

iload_1: 将8从局部变量表中取出放入操作数栈中(现在操作数栈中的数为8)

invokevirtual #3 <java/io/PrintStream.println>:

return:将操作数栈中的数8返回

结论:i=i++;结果为8

---------------------------------------------------------------------------------------------------------------------------------

 

 

上图是i=++i的执行过程,红框中的是jvm的指令集。下面一句一句解释指令集

bipush 8:将8 压入操作数栈

istore_1:将栈顶的数8从操作数栈取出放入局部变量表位置1中(现在int i=8完成,局部变量表中的i的值为8)

inic 1 by 1:将局部变量表中的位置为1的值加1(现在局部变量表中i的值为9)

iload_1: 将局部变量表中位置1的数据9取出放入操作数栈中(现在操作数栈中的数为9)

istore_1:将操作数栈取出位置1的数也就是9放入局部变量表位置1中(局部变量表中的i的值重新赋为9)

getstatic #2:

iload_1: 从局部变量表位置1中取出9放入操作数栈中(现在操作数栈中的数为9)

invokevirtual #3 <java/io/PrintStream.println>:

return:将操作数栈中的数9返回

结论:i=++i;结果为9

最终结论:当i++的时候先将局部变量中数据压入操作数栈然后进行局部变量表中数据加1,++i的时候实现将局部变量表数据加1再压入操作数栈

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值