文档章节

java中关于a++跟++a的操作运算解释

贺小五
 贺小五
发布于 2017/02/11 16:00
字数 1022
阅读 352
收藏 0

昨天,在群里被一个人问了一段代码,代码如下:

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

大家猜猜打印结果是多少,我开始猜的打印结果是9,贴上代码后,才发现,打印结果是6,然后我就很纳闷,怎么是6?查看了一下class文件,然后问了下"腿毛",然后就知道了.下面进入正文吧

 

----------------------------------分割线---------------------------------------

我们都知道,a++跟++a分别是不同的操作,前者是先运算,后自增,后者是先自增,后运算,如果遇到了如下代码:a+(++a)+(++a),运算过程是怎么样呢,先让我们看最简单的

 

PS:首先,引入腿毛知乎的一小段代码(版权费已经给腿毛了,,虽然只有1.11),我就不写了,太麻烦,有兴趣的同学可以自己通过 javap -c XX.class 查看运行指令

 

先看下面这段代码(下面所有指令都是通过查看class文件后得到的,有兴趣的同学,可以自己查看)

int a = 789;
int b;
b = a++;

 

  1. sipush 789 // 把一个789放入栈顶
  2. istore_1 // 把这个789存给a
  3. iload_1 // 把a放到栈顶,栈顶就是789了
  4. iinc 1, 1 // 把a加一,a就是790了
  5. istore_2 // 把栈顶的数存给b,b变成了789

然后,我们改下上面的代码

int a = 789;
int b;
b = ++a;
  1. sipush 789 // 把一个789放入栈顶
  2. istore_1 // 把这个789存给a
  3. iinc 1, 1 // 把a加一,a就是790了
  4. iload_1 // 把a放到栈顶,栈顶就是790了
  5. istore_2 // 把栈顶的数存给b,b变成了790

     也就中间两条指令顺序变了,其他的没有区别

 

好了,下面是重头戏了,贴上文章开头的代码(用红色表示这是我自己的代码...)

        int a = 1;
		int b;
		b = a+(++a)+(++a);
		System.out.println(a); //输出结果是3
		System.out.println(b); //输出结果是6

 

  1. iconst_1          // 数值1放入栈顶
  2. istore_1          // 把1存给a
  3. iload_1           // 把a放到栈顶,栈顶有1了
  4. iinc          1, 1 //把a加一,a就是2了
  5. iload_1          //把a放到栈顶,栈顶有2了
  6. iadd             //栈顶两int型数值相加,栈顶就是3了
  7. iinc        1, 1 //把a加一,a就是3了
  8. iload_1        //把a放到栈顶,栈顶就是3了
  9. iadd           //栈顶两int型数值相加,栈顶就是6了
  10. istore_2     //把6给b,完成运算

 

----------------------------------分割线---------------------------------------

下面是总结,可能个人理解,会有点误差,同学可以自己根据指令来理解

PS:a+(++a)+(++a) 运算过程白话版:

1. a初始化1,入栈顶
2.(++a)运算,a=2,参与内存运算
3.(++a)运算 a=3,参与内存运算
4. 计算:1+2+3
获得结果,并且赋值

 

也就是,参与运算的,并不是a本身,而是a的值...通过指令的调用,a的值每次到栈顶都不一样,a第一次入栈顶的时候是1,第二次入栈顶++a,就是2了,而且a的值会变为2,第三次入栈顶++a,就是3了,而且a的值会变为3,栈顶数值相加就是 1+2+3,可能有人会问,如果这样,应该是3个a相加,但是实际不是的,参与运算的是a的值,不是a本身,每次入栈顶,a的值都会变化,所以就会造成理解的误差,最后在说一句:java运算参与,是变量值的运算,而不是变量本身

 

 

以上..在加一个,如果要查看指令,可以到下面这博客查看:http://blog.csdn.net/lm2302293/article/details/6713147

 

完结,写完,收工!

 

插入个人广告:Python交流群,扫描二维码进入

吾爱java交流群号:170936712(里面有基佬,有萌萌,有大牛...)

欢迎大家入坑!!

 

以上,均为本人测试而得出的结果,可能会有出入,或者错误,欢迎指正

欢迎转载,请注明出处跟作者,谢谢!

 

 

 

 

 

© 著作权归作者所有

贺小五

贺小五

粉丝 72
博文 43
码字总数 44296
作品 0
海淀
程序员
私信 提问
JavaWeb技术内幕七:JVM体系结构和工作方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a724888/article/details/81501369 这位大侠,这是我的公众号:程序员江湖。 分享程序员面试与技术的那些事。...

你的猫大哥
2018/08/08
0
0
Java I/O : Java中的进制详解

作者:李强强 上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算。这一讲,泥瓦匠带你走进Java中的进制详解。 一、引子 在Java世界里,99%的工作都是处理这高层。那么二进制,字节...

泥沙砖瓦浆木匠
2015/06/14
0
0
以一个javaEE程序员的身份来学ruby

做为一个javaEE的程序员,在看关于ruby的资料的时候,难免会以一个对比的眼光来学习ruby,每看到一个和java不一样的地方,就会产生某些想法,先记录下来,待日后来验证。另外,都说Ruby在很多...

茶码古道
2012/07/02
0
0
Android NDK开发之Jni的数据类型

在前面的一篇博客《Android NDK开发简介》,我简单地说明了Android NDK开发的流程,以及其重要的一环:JNI层得开发。今天我再详细说明一下自己的学习经验。 JNI是Java代码和C/C++代码通信的桥...

zhiweiofli
2013/03/15
0
0
Java并发(1)- 聊聊Java内存模型

引言 在计算机系统的发展过程中,由于CPU的运算速度和计算机存储速度之间巨大的差距。为了解决CPU的运算速度和计算机存储速度之间巨大的差距,设计人员在CPU和计算机存储之间加入了高速缓存来...

knock_小新
2018/07/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spark Streaming的优化之路——从Receiver到Direct模式

          作者:个推数据研发工程师 学长 1 业务背景 随着大数据的快速发展,业务场景越来越复杂,离线式的批处理框架MapReduce已经不能满足业务,大量的场景需要实时的数据处理结果来...

个推
47分钟前
2
0
壮丽70年·奋斗新时代|蒸妙集团熏蒸中会阴熏蒸的神奇好处

聚结相合之处为会。会阴居两阴间,为督、任、冲三脉的起点,三脉背出两阴之间,会聚阴部,因名会阴。会阴,经穴名。出《针灸甲乙经》。会阴别名屏翳、下极、金门。属任脉。在会阴部,男性当阴...

公益传承
56分钟前
2
0
pentaho-kettle-8.2.0.0-R源码开发环境搭建

1.从Kettle官网下载源码,本文使用的是pentaho-kettle-8.2.0.0-R 下载地址:https://codeload.github.com/pentaho/pentaho-kettle/zip/8.2.0.0-R 2.打开eclipse,选择一个新的工作空间,然后设...

gq_2010
今天
1
0
lua web快速开发指南(7) - 高效的接口调用 - httpc库

httpc库基于cf框架都内部实现的socket编写的http client库. httpc库内置SSL支持, 在不使用代理的情况下就可以请求第三方接口. httpc支持header、args、body、timeout请求设置, 完美支持各种h...

水果糖的小铺子
今天
5
0
通过四道常问面试题,带你了解什么是数据库分库分表

编者语:为了避免被误解为:「手里有把锤子,看什么都是钉子!」,说明一下不是什么业务都适合分布式数据库,更不是用了分布式数据库性能就一定能得到扩展。 其次:本文为纯干货,建议先转发...

老道士
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部