如果问 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相关推荐

  1. java趣事_【趣事】Java程序员最年轻,C++程序员最年老

    原标题:[趣事]Java程序员最年轻,C++程序员最年老 说起我们对编程世界现有的刻板印象,你一定听说过类似于没有人喜欢用Java编码或者使用C ++都是老人家,等等这样的话.为了分析这些刻板印象背后 ...

  2. JVM总结(面试必备)

    关注我,带了熟悉Java趣事,Java进阶攻略等着你 JVM知识点总结(面试必备) JVM体系总体分为四大块 类的加载机制JVM内存结构GC算法 垃圾回收GC分析 命令调优 类的加载机制 主要关注要点 ...

  3. Java地位被撼动?Java与JavaScript的趣事连载

    第一回 JavaScript的进攻 公元2014年,Java 第八代国王终于登上了王位. 第一次早朝,国王坐在高高的宝座上,看着毕恭毕敬的大臣,第一次体会到了皇权的威力. 德高望重的IO大臣颤悠悠地走 ...

  4. java小丑的毕业设计趣事

    别看一个小小的毕业设计,好多同学是网上下载的,我的是自己做的. 看了马士兵的ssh视频后,感觉大学没白上,大学没有荒废,总比在宿舍打wow强, 于是决定自己写一个小型的blog系统.那必然是NB哄哄的 ...

  5. 0基础小白学好JAVA的5个方法

    JAVA分两个大方向web企业级开发(JavaWeb J2EE)和手机android开发.一般从事Java的开发人员都会从J2SE开始学习,因此对于J2SE的掌握必须要牢固.然而在初期学习时,通常会对 ...

  6. Java性能调优、LinkedIn容器部署、阿里移动性能调优——首届APMCon精彩演讲先睹为快...

    APMCon2016,在盛夏的8月等你. \\ 作为第一届APM垂直领域的技术大会,我们能拿出什么呈现给参会者? \\ 答案是,除了会场可以纳凉避暑之外,还有来自国内外顶级技术大拿带来的Java性能管 ...

  7. java api 设计_Java API设计实践

    使你的API在模块化和非模块化Java环境中都可用 在优锐课的java学习分享中,对微服务有了更深层次的新概念.关于API设计实践一点就通了. 介绍 了解设计Java API时应应用的一些API设计实 ...

  8. 盘点 6 个被淘汰的 Java 技术,它们都曾经风光过!| CSDN 博文精选

    作者 | 栈长 责编 | 屠敏 出品 | CSDN 博客 今天给大家分享下我的开发历程中,我知道的那些被淘汰的技术或者框架,有些我甚至都没有用过,但我知道它曾经风光过. 废话不多说,下面我要开始吹了- ...

  9. JAVA学习之路 不走弯路,就是捷径

    [霄潇] 软件开发之路是充满荆棘与挑战之路,也是充满希望之路.JAVA学习也是如此,没有捷径可走.梦想像<天龙八部>中虚竹一样被无崖子醍醐灌顶而轻松获得一甲子功力,是很不现实的.每天仰天大 ...

最新文章

  1. mockito mock void方法_一文让你快速上手 Mockito 单元测试框架(上)
  2. 电信业务分类目录2019_2019年1月国内增值电信业务许可情况分析报告,市场区域发展不均衡...
  3. python魔法方法str_8.9.魔法方法 - str()方法
  4. 香肠派对电脑版_《香肠派对》是不是除了《和平精英》最成功的吃鸡手游:靠恶搞火了?...
  5. linux 中阻塞与非阻塞 同步与异步
  6. java衍生作用_关于JAVA衍生出的一点想法
  7. linux那些事之 page translation(硬件篇)
  8. 美团互助关停:聚焦主业发展 将全额返还会员分摊
  9. 解决CentOS6.5下MySQL5.6无法远程连接的问题
  10. mac php5.6 gd 扩展,mac 编译安装php5.6.40
  11. 《重构HTML改善Web应用的设计》读书笔记
  12. 使用ListBox控件来实现直方图控件(一)
  13. Python Flask Web 第三课 —— 模板
  14. Mysql安装的目录结构详解
  15. centos7 redis分布式集群问题总结
  16. 454.四数相加II
  17. 妙味课堂原创JavaScript视频教程基础+提高+项目
  18. 如何使用小米手机的便签功能
  19. SpringBoot基础-refresh方法解析
  20. Mac电脑浏览器无法上网

热门文章

  1. C语言 模拟键盘、鼠标事例
  2. TypeScript——Web前端开发的救赎
  3. v-model的radio checkbox以及键盘修饰符使用
  4. 地铁译:Spark for python developers ---Spark的数据戏法
  5. 权重初始化方法及适用情况
  6. 【Lilishop商城】No2-1.确定项目结构和数据结构(用户、商品、订单、促销等模块)
  7. 大数据舆情传播演变规律如何分析的方法技巧
  8. oracle修改日历,oracle 日历
  9. 紫羚云秦鸿林:大中型企业实施IT服务管理(ITSM)的几大难题
  10. CDR中实现浮雕效果的两种方法