转自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(转)的更多相关文章

  1. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

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

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

  3. Java 诞生的趣事

    ​ Java 命名的由来 Java是印度尼西亚爪哇岛的英文名称,因盛产咖啡而闻名.Java语言中的许多库类名称,多与咖啡有关:如JavaBeans(咖啡豆).NetBeans(网络豆)以及Object ...

  4. Java学习之路:不走弯路,就是捷径

    1.如何学习程序设计? JAVA是一种平台,也是一种程序设计语言,如何学好程序设计不仅仅适用于JAVA,对C++等其他程序设计语言也一样管用.有编程高手认为,JAVA也好C也好没什么分别,拿来就用.为 ...

  5. Java自学成长路线(转载)

    JAVA自学之路 一:学会选择  决心做软件的,大多数人选的是java,或是.net,也有一些选择了手机.嵌入式.游戏.3G.测试等.  JAVA是一种平台,也是一种程序设计语言,如何学好程序设计不仅 ...

  6. Java学习路径:不走弯路,这是一条捷径

    1.如何学习编程? JAVA是一种平台.也是一种程序设计语言,怎样学好程序设计不只适用于JAVA,对C++等其它程序设计语言也一样管用.有编程高手觉得,JAVA也好C也好没什么分别,拿来就用.为什么他 ...

  7. JAVA NIO学习三:NIO 的非阻塞式网络通信

    紧接着上一章,我们继续来研究NIO,上一章中我们讲了NIO 中最常见的操作即文件通道的操作,但实际上NIO的主要用途还是在于网络通信,那么这个时候就会涉及到选择器,这一章我们就会对其进行讲解操作. 一 ...

  8. Java NIO之网络编程

    最近在研究Java NIO和netty,曾经一度感觉很吃力,根本原因还是对操作系统.TCP/IP.socket编程的理解不到位. 不禁感叹,还是当初逃的课太多. 假如上天给我一次机会,能够再回到意气风 ...

  9. JAVA NIO工作原理及代码示例

    简介:本文主要介绍了JAVA NIO中的Buffer, Channel, Selector的工作原理以及使用它们的若干注意事项,最后是利用它们实现服务器和客户端通信的代码实例. 欢迎探讨,如有错误敬请 ...

随机推荐

  1. Directx11教程(65) 渲染到纹理

    原文:Directx11教程(65) 渲染到纹理     通常情况下,我们的render target都是后缓冲,但也可以把render target设置为一个2d 纹理,然后再通过贴图的方式,把这个 ...

  2. Length of Last Word输出最后单词的字母个数

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  3. 【JZOJ4846】【NOIP2016提高A组集训第5场11.2】行走

    题目描述 数据范围 对于70%的数据保证 n <= 1000 对于100%的数据保证 n,q <= 10^5,c_i,v_i <= 10^{18} 保证每次修改后的边权小于等于原来的 ...

  4. 2019-3-21-win10-uwp-修改图片质量压缩图片

    title author date CreateTime categories win10 uwp 修改图片质量压缩图片 lindexi 2019-03-21 15:29:20 +0800 2019- ...

  5. maven 从svn导入项目遇到的问题 No marketplace entries found to handle yuicompressor maven plugin:1.3.0:compile

    版权声明:本文为博主原创文章,未经博主同意不得转载.安金龙 的博客. https://blog.csdn.net/smile0198/article/details/25463825 RT.使用ecl ...

  6. sql.date

    package com.sxt.utils.date1; import java.sql.Date; /* * sql.date:没有时,分,秒 */ public class TestDate2 { ...

  7. 中断源记录 INT0 INT1

    中断源记录 INT0 INT1 用到一个单片机 使用的 P3.1 P3.3 作为唤醒口,后来发一 P3.1 和 P3.3 使用的同一个中断 INT1,这个尴尬了,只能两选 一. 查看规格书,还好 P3 ...

  8. 2019-7-25-VisualStudio-2019-新创建项目添加-git-仓库

    title author date CreateTime categories VisualStudio 2019 新创建项目添加 git 仓库 lindexi 2019-7-25 15:8:15 + ...

  9. oracle函数 NLS_LOWER(x[,y])

    [功能]返回字符串并将字符串的变为小写; [参数]x字符型表达式 [参数]Nls_param可选,指定排序的方式(nls_sort=) . SCHINESE_RADICAL_M(部首.笔画) SCHI ...

  10. 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)

    洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...