Java 趣事之 a=a++ 和 a=++a(转)
转自: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
Java 趣事之 a=a++ 和 a=++a(转)的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- Java地位被撼动?Java与JavaScript的趣事连载
第一回 JavaScript的进攻 公元2014年,Java 第八代国王终于登上了王位. 第一次早朝,国王坐在高高的宝座上,看着毕恭毕敬的大臣,第一次体会到了皇权的威力. 德高望重的IO大臣颤悠悠地走 ...
- Java 诞生的趣事
Java 命名的由来 Java是印度尼西亚爪哇岛的英文名称,因盛产咖啡而闻名.Java语言中的许多库类名称,多与咖啡有关:如JavaBeans(咖啡豆).NetBeans(网络豆)以及Object ...
- Java学习之路:不走弯路,就是捷径
1.如何学习程序设计? JAVA是一种平台,也是一种程序设计语言,如何学好程序设计不仅仅适用于JAVA,对C++等其他程序设计语言也一样管用.有编程高手认为,JAVA也好C也好没什么分别,拿来就用.为 ...
- Java自学成长路线(转载)
JAVA自学之路 一:学会选择 决心做软件的,大多数人选的是java,或是.net,也有一些选择了手机.嵌入式.游戏.3G.测试等. JAVA是一种平台,也是一种程序设计语言,如何学好程序设计不仅 ...
- Java学习路径:不走弯路,这是一条捷径
1.如何学习编程? JAVA是一种平台.也是一种程序设计语言,怎样学好程序设计不只适用于JAVA,对C++等其它程序设计语言也一样管用.有编程高手觉得,JAVA也好C也好没什么分别,拿来就用.为什么他 ...
- JAVA NIO学习三:NIO 的非阻塞式网络通信
紧接着上一章,我们继续来研究NIO,上一章中我们讲了NIO 中最常见的操作即文件通道的操作,但实际上NIO的主要用途还是在于网络通信,那么这个时候就会涉及到选择器,这一章我们就会对其进行讲解操作. 一 ...
- Java NIO之网络编程
最近在研究Java NIO和netty,曾经一度感觉很吃力,根本原因还是对操作系统.TCP/IP.socket编程的理解不到位. 不禁感叹,还是当初逃的课太多. 假如上天给我一次机会,能够再回到意气风 ...
- JAVA NIO工作原理及代码示例
简介:本文主要介绍了JAVA NIO中的Buffer, Channel, Selector的工作原理以及使用它们的若干注意事项,最后是利用它们实现服务器和客户端通信的代码实例. 欢迎探讨,如有错误敬请 ...
随机推荐
- 【JZOJ4925】【GDOI2017模拟12.18】稻草人
题目描述 YLOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,YLOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条 ...
- 【51NOD1304】字符串的相似度
题目描述 我们定义2个字符串的相似度等于两个串的相同前缀的长度.例如 "abc" 同 "abd" 的相似度为2,"aaa" 同 " ...
- Nginx教程(二) Nginx虚拟主机配置 (转)
Nginx教程(二) Nginx虚拟主机配置 1 虚拟主机管理 1.1 Nginx管理虚拟主机 虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主 ...
- 【python小随笔】单例模式设计(易懂版)
1:单例模式原理 大道理:希望在系统中某个对象只能存在一个,单例模式是最好的解决方案,单例模式是一种常见的软件设置模式,在它的核心结构中只包含一个被称为单例类的特殊类,通过单例模式可以保证系统中的一个 ...
- python 面向对象编程语言
- More Effective C++: 03异常
C++的异常机制使得程序付出某些代价:资源泄漏的可能性增加了:写出具有你希望的行为的构造函数与析构函数变得更加困难:执行程序和库程序尺寸增加了,同时运行速度降低了等等. 但是为什么使用异常呢?C程序使 ...
- 使用iPhone为Apple Watch制作动画
(原文:Make Animations for APPLE WATCH Using iPhone 作者:Andy Drizen 译者:xiaoying) 无论要做一个像hamburger button ...
- TIJ——Chapter Twelve:Error Handling with Exception
Exception guidelines Use exceptions to: Handle problems at the appropriate level.(Avoid catching exc ...
- OpenJudge_1477:Box of Bricks
描述 Little Bob likes playing with his box of bricks. He puts the bricks one upon another and builds s ...
- laravel 博客项目部署到Linux系统后报错 权限都设置为777,仍然报错没有权限
阿里工程师最后给出解决方案.