JVM角度分析i++和++i的区别

JVM角度分析i++和++i的区别

最近看JVM的一些相关知识,看到i++和++i的指令执行过程,知道的其实也没啥难的,不知道的估计也说不出为什么两个赋值结果不一样。跟大伙分享分享我的理解。

前置知识

首先要知道虚拟机栈是什么?虚拟机栈里都有什么?此知识点要掌握关于虚拟机栈中的操作数栈(以下用操作栈代替)和局部变量表(以下用局部表代替),还有JVM的基本指令。下面会主要涉及到局部表和操作栈还有JVM指令这块的知识。网上一大堆我就不详细说明了。

详解

public static void main(String[] args) {
    int i = 100;
    i = i++;	//代码1
}
public static void main(String[] args) {
    int i = 100;
    i = ++i;	//代码2
}

两块代码很简单,就一个i++的赋值和++i的赋值。很显然 代码1的结果是0,代码2的结果是1.为什么呢?
主要是因为JVM的指令操作不一样。

代码一的JVM执行指令
在这里插入图片描述
代码2的JVM执行指令
在这里插入图片描述
感觉两个都差不多,区别在哪,区别就在与执行iinc这个指令后的操作。先一步步看
bipush 100: 意思就是将100 压栈到操作数栈中。
istore_1 :将操作数栈中的栈顶元素(值)存到局部变量表中的第一个(index=1)位置,
iinc 1 by 1 :这个看插件,有的地方写的是 iinc 1,1
意思是将局部表中的第一个位置的变量按常量1增加。
第一个位置1代表索引,第二个1表示常量。
重点来了
iload_1:从局部表中的第一个变量的值出栈到操作数栈中。
相当于从局部表中读了第一个数据然后存到操作表中。可以这么简单的理解。
区别就在于
i++是直接将操作表中数据存到局部表中。
而++i是先读取的局部表中的数据到操作栈,然后在从操作栈存到局部表中。
为什么这样做?主要是因为iinc这个命令,这个命令是操作的是局部表。

i++:
	iinc 执行之前是 局部表中变量值是100的而操作栈里的值也是100.
	但是执行完iinc命令后是局部表中值变成101,而操作栈中的值依然是100;最后执行istore局部表变100.
++i:
	iinc执行之前是局部表中变量值是100,而操作栈里是空的。
	iinc执行完后局部表中是101,由于执行了iload操作栈也是101.最后执行了istore最终局部表变101.

但是
上面的代码都是有 “=” 符号的。假如没有“=” 符号会发生什么。
在这里插入图片描述
当你不做任何赋值的时候++i和i++是没有区别的。当赋值的时候才会存在区别。

结论

i++和++i最终的区别其实就在于有没有去读局部表中的变量的值。

小白第一次写博客,说的写的不对的,有错误的请指出,一起探讨,尽快做修正,以免误导别人。
感谢大家!!!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最后一根头发

努力分享自己的经验谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值