Java 趣事之 a=a++ 和 a=++a
如果问 a++
和 ++a
的区别,估计很多都能回答上来。a++
是先取 a 的值再自增 。而 ++a
刚好相反,是先自增再取 a 的值。这里有点编程基础都可以理解,不做过多解释,但在 Java 里面事情就真的这么简单吗?
int a = 1;
a = a++;
System.out.println(a);
凭借自己所学,在不测试的情况下,你能给出答案吗?
第一次看见这个问题的时候,想当然的认为答案是: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);
直接上截图吧
仔细对比一下,你会发现,两段代码的指令一模一样,但执行顺序有一点点区别, iinc 和 iload_1 这两个命令的执行顺序变化了一下位置。你还记得这两条指令的含义吗?你还记得文章最开始说的区别吗?
是不是很奇妙?知其然,知其所以然。
参考网址:https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
参考书籍:《深入理解Java虚拟机》(周志明著)
欢迎大家关注我的微信公众号:卡戎
如有错误,欢迎留言!
Java 趣事之 a=a++ 和 a=++a相关推荐
- java趣事_【趣事】Java程序员最年轻,C++程序员最年老
原标题:[趣事]Java程序员最年轻,C++程序员最年老 说起我们对编程世界现有的刻板印象,你一定听说过类似于没有人喜欢用Java编码或者使用C ++都是老人家,等等这样的话.为了分析这些刻板印象背后 ...
- JVM总结(面试必备)
关注我,带了熟悉Java趣事,Java进阶攻略等着你 JVM知识点总结(面试必备) JVM体系总体分为四大块 类的加载机制JVM内存结构GC算法 垃圾回收GC分析 命令调优 类的加载机制 主要关注要点 ...
- Java地位被撼动?Java与JavaScript的趣事连载
第一回 JavaScript的进攻 公元2014年,Java 第八代国王终于登上了王位. 第一次早朝,国王坐在高高的宝座上,看着毕恭毕敬的大臣,第一次体会到了皇权的威力. 德高望重的IO大臣颤悠悠地走 ...
- java小丑的毕业设计趣事
别看一个小小的毕业设计,好多同学是网上下载的,我的是自己做的. 看了马士兵的ssh视频后,感觉大学没白上,大学没有荒废,总比在宿舍打wow强, 于是决定自己写一个小型的blog系统.那必然是NB哄哄的 ...
- 0基础小白学好JAVA的5个方法
JAVA分两个大方向web企业级开发(JavaWeb J2EE)和手机android开发.一般从事Java的开发人员都会从J2SE开始学习,因此对于J2SE的掌握必须要牢固.然而在初期学习时,通常会对 ...
- Java性能调优、LinkedIn容器部署、阿里移动性能调优——首届APMCon精彩演讲先睹为快...
APMCon2016,在盛夏的8月等你. \\ 作为第一届APM垂直领域的技术大会,我们能拿出什么呈现给参会者? \\ 答案是,除了会场可以纳凉避暑之外,还有来自国内外顶级技术大拿带来的Java性能管 ...
- java api 设计_Java API设计实践
使你的API在模块化和非模块化Java环境中都可用 在优锐课的java学习分享中,对微服务有了更深层次的新概念.关于API设计实践一点就通了. 介绍 了解设计Java API时应应用的一些API设计实 ...
- 盘点 6 个被淘汰的 Java 技术,它们都曾经风光过!| CSDN 博文精选
作者 | 栈长 责编 | 屠敏 出品 | CSDN 博客 今天给大家分享下我的开发历程中,我知道的那些被淘汰的技术或者框架,有些我甚至都没有用过,但我知道它曾经风光过. 废话不多说,下面我要开始吹了- ...
- JAVA学习之路 不走弯路,就是捷径
[霄潇] 软件开发之路是充满荆棘与挑战之路,也是充满希望之路.JAVA学习也是如此,没有捷径可走.梦想像<天龙八部>中虚竹一样被无崖子醍醐灌顶而轻松获得一甲子功力,是很不现实的.每天仰天大 ...
最新文章
- mockito mock void方法_一文让你快速上手 Mockito 单元测试框架(上)
- 电信业务分类目录2019_2019年1月国内增值电信业务许可情况分析报告,市场区域发展不均衡...
- python魔法方法str_8.9.魔法方法 - str()方法
- 香肠派对电脑版_《香肠派对》是不是除了《和平精英》最成功的吃鸡手游:靠恶搞火了?...
- linux 中阻塞与非阻塞 同步与异步
- java衍生作用_关于JAVA衍生出的一点想法
- linux那些事之 page translation(硬件篇)
- 美团互助关停:聚焦主业发展 将全额返还会员分摊
- 解决CentOS6.5下MySQL5.6无法远程连接的问题
- mac php5.6 gd 扩展,mac 编译安装php5.6.40
- 《重构HTML改善Web应用的设计》读书笔记
- 使用ListBox控件来实现直方图控件(一)
- Python Flask Web 第三课 —— 模板
- Mysql安装的目录结构详解
- centos7 redis分布式集群问题总结
- 454.四数相加II
- 妙味课堂原创JavaScript视频教程基础+提高+项目
- 如何使用小米手机的便签功能
- SpringBoot基础-refresh方法解析
- Mac电脑浏览器无法上网