文档章节

ITeye上“10个人,8个人不会解释这个问题”的帖子

canghailan
 canghailan
发布于 2011/11/17 16:10
字数 644
阅读 256
收藏 1

原帖链接:http://www.iteye.com/topic/1117960

简单说一下问题,LZ要求解释下面的Java代码,x为什么最后是1。

Integer x = 1;
x = x++;
System.out.println(x);

不管这么说,我觉得这个问题还不错,这个帖子最后还是被隐藏了,事实上这个帖子并没有“标题党”。 不得不说ITeye上的风气是越来越浮躁了,为什么就不肯静下心来好好讨论呢,至少给出理由给出证据,而不是随手投个隐藏。

OK,进入正题。

这里表面上是关于x++的讨论,但实际上也涉及到Java中自动拆装箱的问题。

首先看《The Java Language Specification, Third Edition》15.14.2 Postfix Increment Operator ++的描述:

A postfix expression followed by a ++ operator is a postfix increment expression. The result of the postfix expression must be a variable of a type that is convertible (§5.1.8) to a numeric type, or a compile-time error occurs. The type of the postfix increment expression is the type of the variable. The result of the postfix increment expression is not a variable, but a value.

At run time, if evaluation of the operand expression completes abruptly, then the postfix increment expression completes abruptly for the same reason and no incrementation occurs. Otherwise, the value 1 is added to the value of the variable and the sum is stored back into the variable. Before the addition, binary numeric promotion (§5.6.2) is performed on the value 1 and the value of the variable. If necessary, the sum is narrowed by a narrowing primitive conversion (§5.1.3) and/or subjected to boxing conversion (§5.1.7) to the type of the variable before it is stored. The value of the postfix increment expression is the value of the variable before the new value is stored.

Note that the binary numeric promotion mentioned above may include unboxing conversion (§5.1.8) and value set conversion (§5.1.13). If necessary, value set conversion is applied to the sum prior to its being stored in the variable.

这儿明确说明了:(1)拆箱(unboxing conversion);(2)将变量的值加一的和存储回这个变量;(3)这个表达式的值为将新值存储回变量之前变量的值;(4)装箱(boxing conversion)。

用Java代码表示x=x++即:

int int_x = x.intValue();
int exprValue = int_x;
int_x = int_x + 1;
Integer integer_exprValue = Integer.valueOf(exprValue);
x = integer_exprValue;

事实上从class文件中也可以看出:

0 iconst_1
 1 invokestatic #2 <java/lang/Integer.valueOf>
 4 astore_1
 5 aload_1
 6 astore_2
 7 aload_1
 8 invokevirtual #3 <java/lang/Integer.intValue>
11 iconst_1
12 iadd
13 invokestatic #2 <java/lang/Integer.valueOf>
16 dup
17 astore_1
18 astore_3
19 aload_2
20 astore_1
21 getstatic #4 <java/lang/System.out>
24 aload_1
25 invokevirtual #5 <java/io/PrintStream.println>
28 return

PS:当初发现JavaEye的时候,感叹CSDN的没落,没想到现在轮到ITeye了。不过还好,ITeye上还有RednaxelaFX,wenshao,icyfenix等大牛。衷心希望有更多的好论坛出现~ 同时求推荐一些好的技术论坛

 

© 著作权归作者所有

canghailan

canghailan

粉丝 28
博文 14
码字总数 10765
作品 0
武汉
程序员
私信 提问
加载中

评论(5)

canghailan
canghailan 博主

引用来自“赵渊”的评论

字节码是这样的:我看不懂,但是看起来和装箱拆箱没有关系
0: iconst_1
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
恩,本质上的确是这个解释。int类型的解释非常明了,不过Integer类型里隐藏了一些细节,虽然无关结果,但我觉得这个问题还是有些价值。 JLS中谈论这个运算符时专门提到过拆装箱问题,我的意思只是想提醒大家注意这个细节。 你可以把i的类型换成Integer,再看看字节码,如果编译器没有优化的话,与你现在的字节码是有所不同的。
司马长风kill
司马长风kill
黄老师,最近拜读了您的webmagic,分布式那个没有太搞懂,
是不是就是对URL用redis进行了管理
如果我要爬取各种不同的新闻,论坛,博客等, 那么这个还试用么。
个人感觉这个怎么跟理解的分布式有点出入
赵渊
赵渊
++ 这个表达式相当于这样一个函数:
function(int i){
int temp = i;
i += 1;
return temp;
}

在i = i++这个语句中,i的自增操作在 重新给i赋值前就已经执行了。不是在这个语句之后执行的。
在i++的时候,i其实已经等于2了,但是i++这个表达式的返回值是1.
然后将i++这个表达式的返回值,赋值给i,所以i又变成1了。

我没研究过字节码,这个在有本书上看到的。你看对不对
赵渊
赵渊
结果等于1和装箱拆箱没有关系吧。
看这段代码:
int i = 1;
i = i++;
System.out.println(i);

实际上影响结果的事 ++ 这个操作的实现方式
苗哥
苗哥
内容分析得很好很到位,就是感觉楼主也有点标题党,建议把标题修改为比较有意义的,比如说“浅析Java中自动拆装箱”,仅供参考,谢谢!
ThinkSNS V4.5发布,新增更多趣味交互功能

ThinkSNS V4.5强势发布,不一样的页面体验,不一样的功能布局,人性化的功能操作,除对原系统进行整体优化外,新增多种功能,增强用户互动性、趣味性。 ThinkSNS直播版(ThinkSNS+Zhibo系统)...

ThinkSNS账号
2016/11/02
2.3K
5
关于技术思路的杂乱篇章【更新2011-11-6】

1. 隔壁的office在申请一个专利, 通过操作手机的方式去操纵设备。 手机的系统采用的是Android。 希望我能参与制作手机客户端控制, 于是搜集一些关于手机控制的案例, 自己做了一下引申。大致的...

晨曦之光
2012/03/09
153
0
想到个功能,请教大神们。它的占用资源多少和解决办法。

我网站是门户信息类的,希望活跃用户,如果某帖子0个评论,接下来有个会员进行了评论,会员每个评论的帖子都会记录在他们自己的会员中心,只可以自己查看,而会员中心对评论记录是简单的页面...

豪杰也许本疯子
2015/01/17
169
2
Chrome漏洞允许黑客获取个人私密数据

     随着Chrome 68的发布,Google在其浏览器上突出显示所有非HTTPS网站为“不安全”来源,这一举动使互联网更安全。   在更新之前,还有另一个重要的原因,使需要立即切换最新版本的C...

嘶吼RoarTalk
2018/08/21
0
0
逻辑编程被低估了

Mark Engelberg写了一篇有意思的帖子名为 逻辑编程被高估了。 我在那个帖子中摆出许多观点与之争论,同时我也愿意将其中的一些放到这里来讲一讲。 首先,确实,当搜索范围相当小而你又真的不...

oschina
2013/06/09
770
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周五乱弹 —— 要步入《攻壳机动队》的世界了么?

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @ nnnm:说到音乐,这段一直是纯音乐在循环。每次听到久石让的Summer时心上都会莫名的感觉着轻松。《菊次郞的夏天》竟然是北野武的片子,没有...

小小编辑
42分钟前
122
8
C++ STL set::find的用法

参考: http://blog.csdn.net/lihao21/article/details/6302196 /* class for function predicate * - operator() returns whether a person is less than another person */ c......

shzwork
51分钟前
1
0
抽象同步队列AQS——AbstractQueuedSynchronizer锁详解

AQS——锁的底层支持 谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)! 类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资...

须臾之余
今天
3
0
springboot配置百度UEditor 富文本详解

富文本简介 UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码... 准备工作 ueditor需要单独文...

wotrd
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部