转自https://blog.csdn.net/LovePluto/article/details/81062176

如果问 a++ 和 ++a 的区别,估计很多都能回答上来。a++ 是先取 a 的值再自增 。而 ++a 刚好相反,是先自增再取 a 的值。这里有点编程基础都可以理解,不做过多解释,但在 Java 里面事情就真的这么简单吗?

int a = 1;
a = a++;
System.out.println(a);

输出是1

凭借自己所学,在不测试的情况下,你能给出答案吗?

第一次看见这个问题的时候,想当然的认为答案是:2。但残酷的事实告诉我,答案是:1。当时面对这个结果我是无法接受的,网上疯狂搜索这个答案的解释。限于当时知识的水平,只记住了这个结论,至于推导这个结论那些指令,一个也不能理解。今天看书遇见数据操作,就又想起了这个问题,就根据自己的知识水平,重新推导这个过程。

首先用 IDEA 打开生成的 class 文件。

很直观的告诉我们结果为 1 ,但这段代码只解释了 result,而没有解释 why ,继续用 javap -c 这个命令,结果如图。

以第一次遇见这道题的水准,勉强能看懂第一步的 Java 代码,第二步的指令就彻底看不懂了。而现在我可以从这些指令里面分析结果了(这里需要分析的就前五行命令,后面指令为打印输出)。

iconst_1

将常量 1 压入操作数栈。这个操作是 int 值为 1~5 的时候。如果是 -128~127 这个范围是用的 bipush x (x 为实际数值)。 -2^15~2^15-1 这个范围是使用的 sipush x 这个命令(同上)。 -2^31~2^31-1 这个范围是使用的 ldc 这个命令。

istore_1

弹出操作数栈顶的数(此时为 1)并赋值给局部变量第一个元素即索引为 1 的 a。局部变量是采用的数组形式,索引为 0 的是 main() 的参数 args 。

iload_1

把局部变量索引为 1 的变量(这里是 a)压入操作数栈,此时栈顶元素为 1 。

incc 1,1(关键)

把局部变量索引为 1 的数加 1 ,此时 a 的值为 2。注意:这个结果没有压入操作数栈。

istore_1

弹出栈顶的元素(此时为 1)赋值给 a ,覆盖 a 为 2 的结果。

整个过程大致就是这样,来一幅图解释吧。

这个问题解决了,那么下面这段代码就好理解了。

int a = 1;
a = ++a;
System.out.println(a);
输出是2
直接上截图吧

仔细对比一下,你会发现,两段代码的指令一模一样,但执行顺序有一点点区别, iinc 和 iload_1 这两个命令的执行顺序变化了一下位置。
是先给索引为1的变量(这里是a) 加了1,再把这个数压入操作数栈,最后再赋值回索引为1的变量

自己记录

iconst 获得初始值加入操作栈
istore 初始值赋值给a
iload 把a加入操作数栈
incc 1,1 把局部变量的a+1
istore 再把操作数栈的赋值给a

最新文章

  1. Oracle操作
  2. canvas孙悟空脚踩白云今年是猴年
  3. hibernate 异常:Unexpected Exception caught setting
  4. git merge之squash
  5. Java Web连接各种数据库方式汇总
  6. 使用 Windows PowerShell 管理Windows Azure映像
  7. 如何正确的在java web配置数据池
  8. Intellij Idea自动加载改动文件和自动自动热部署加载
  9. Mysql 基于日志点的主从复制(实操)
  10. System.Object简介
  11. js内存深入学习(一)
  12. 【原创】驱动开发中Memory read error导致的蓝屏问题
  13. JVM、Gc工作机制详解
  14. 数据迁移工具Sqoop和DataX功能比较
  15. a标签自执行点击事件
  16. POJ 1112 Team Them Up! 二分图判定+01背包
  17. PyCharm安装与配置,python的Hello World
  18. 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)
  19. Kubernetes 1.5部署sonarqube
  20. js 内存泄漏

热门文章

  1. Directx11教程(5) 画一个简单的三角形(1)
  2. iOS:你App的设置做对了吗?
  3. python 利用pandas导入数据
  4. mysqldump导出表结构或者表数据
  5. docker-其它命令
  6. hdu1564 简单博弈
  7. 【NS2】TCL debug (转载)
  8. 利用idea构建hibernate
  9. 5-2 正则表达式及其re模块
  10. oracle函数greatest(exp1,exp2,exp3,……,expn)