通过javap来看看前自增和后自增

今天因为一个偶然的原因,想要认认真真的去验证一下前自增和后自增到底的本质区别,因为,从一开始我们学习编程语言,学习前自增和后自增,我们的老师就告诉我们,记住它们的区别,前自增是先使用变量的值,再对变量进行+1,后自增是先对变量进行+1,再使用变量的值,也不是说着中说法不对,其实我们在使用过程中,确实与这个结论并不相违背,但是就是偶尔出现一些诡异的现象,让我想去一探究竟。
很早之前就使用过javap,去验证一些东西,比如构造函数,比如接口、枚举,但是也只是粗略的看一个大概,对于反编译出来的一些汇编指令也是看个大概意思,没有深究,这次就借助javap这个指令,好好分析一下前自增和后自增的区别

先来第一轮验证,代码很简单:
在这里插入图片描述
然后通过javap反编译看看指令:
在这里插入图片描述
为了便于理解,这里对每一行指令进行解释
Code:
0: iconst_1 //将常量1置于栈顶
1: istore_1 //将栈顶数据(即1)保存到变量1(即i)中
2: iinc 1, 1 //对变量1进行+1操作,此时变量1的值是2
5: iconst_1 //将常量1置于栈顶
6: istore_2 //将栈顶数据(即1)保存到变量1(即i)中
7: iinc 2, 1 //对变量2进行+1操作,此时变量2的值是2
10: return
很明显,反编译出来的指令时完全一样的,所以,我们可以下个这样的结论,单纯的前自增和后自增的执行原理没有任何区别。

有了第一轮的基础之后,我们再来验证第二轮,代码如下:
在这里插入图片描述
首选,这一段代码执行后的结果,我们都知道i = 1, j = 2
个我们之前接触的那套理论依然不冲突,关键是有一个地方很多人想不明白,就是不管怎么样,你i最终还是自增了呀,怎么还是1呢。通过反编译的结果我们就可以很清晰的理解了。
在这里插入图片描述
再次解释一下每一行指令的意思:
Code:
0: iconst_1 //将常量1置于栈顶
1: istore_1 //将栈顶数据保存到变量i中
2: iload_1 //将变量i的值置于栈顶
3: iinc 1, 1 //对变量i进行+1操作,i的值为2
6: istore_1 //将栈顶数据(i自增前的值)保存到变量i,i重新变为1
7: iconst_1 //将常量1置于栈顶
8: istore_2 //将栈顶数据保存到变量j中
9: iinc 2, 1 //对变量j进行+1操纵,j的值为2
12: iload_2 //将j的值置于栈顶 (注意此时j的值已经是2)
13: istore_2 //将栈顶数据保存到变量j中
14: return
所以很明显,前自增和后自增在参与运算的时候有一个非常重要的区别,就是何时将变量的值置于栈顶
在这里插入图片描述
验证到此结束,其实中间应该还加上两个简单一点的验证,就是如下两种:
1、
在这里插入图片描述
2、
在这里插入图片描述
不过,我的第二个验证本身就包含这两中情况中的特殊情况,所以直接跳过了,不是很明白的同学可以自己去验证一下这两种情况。

猜你喜欢

转载自blog.csdn.net/u012230676/article/details/85782471