天天看点

从 JVM 层面理解 i++ 和 ++i 的真正区别!

如果只用普通的知识解释i++和++i的话

i++ 先将i赋值再++

++i 先++再赋值

但是这简单的回答并不能入吸引面试官的眼球,如果用java字节码指令分析则效果完全不同。

运行结果

从 JVM 层面理解 i++ 和 ++i 的真正区别!

通过<code>javap -v out</code>目录下的class文件名 在终端运行得到如下结果

第一类问题

对应的指令为

从 JVM 层面理解 i++ 和 ++i 的真正区别!

先将i1的值为10入栈(bipush),然后将int类型的值从栈中存到局部变量表0的位置,然后执行iinc将0位置的值+1,然后将局部变量表0位置的数入栈执行输出操作

所以i1的值为11

先将i2的值为10入栈(bipush),然后将int类型的值从栈中存到局部变量表1的位置,然后执行iinc将1位置的值+1,然后将局部变量表1位置的数入栈执行输出操作

所以i2的值为11

由于没有赋值操作,区别不大。

第二类问题

从 JVM 层面理解 i++ 和 ++i 的真正区别!
从 JVM 层面理解 i++ 和 ++i 的真正区别!

先将i3入栈存储到局部变量表2的位置,然后将它入栈,执行iinc将2位置的值加一,i4存储到局部表量表3的位置

所以i3是11,i4还是10

将i5入栈存储到局部变量表4的位置,由于是++i所以先iinc将4位置的值加一,然后将局部变量表4的值入栈,执行赋值操作,所以都是11

第三类问题

从 JVM 层面理解 i++ 和 ++i 的真正区别!
从 JVM 层面理解 i++ 和 ++i 的真正区别!

先将i7入栈,然后存到局部变量表6的位置,先把i6入栈,然后把6处的值加一,由于又将这个值存储到局部变量表6处,所以产生覆盖又把值变为10。

而++i不会产生覆盖先执行加一然后再把值入栈,在赋值给局部变量表中,所以i8为11。

第四类问题

从 JVM 层面理解 i++ 和 ++i 的真正区别!
从 JVM 层面理解 i++ 和 ++i 的真正区别!

先将i9=10入栈,然后存在局部变量表8的位置

先iload将8位置的i9入栈然后执行iinc将8处的i9加一,然后执行++i9,在将8处的i9加一

此时i9=10+1+1为12,然后将8位置的i9入栈,执行add将栈中的两i9相加,得到的值存储到局部变量表9的位置

所以i10=10+12(i9++后还是10,++i9后是12,因为执行了两次iinc操作)

然后调用虚方法和静态方法,在将9处的值入栈执行输出语句

本文为「默默无闻代码人」的原创文章

下一篇: I2C总线