下面是几道Java谜题,不仔细分析就会犯错哦。看来看下面的一段代码:
代码片段1:
public static void main(final String[] args) {
Integer a = new Integer(100);
Integer b = 100;
System.out.println(a == b); }
这段代码的输出是什么?相信很多人都会很容易的猜到:false,因为a、b两个对象的地址不同,用"=="比较时是false.恭喜你,答对了。
再看下面的一段代码:
代码片段2:
public static void main(final String[] args) {
Integer a = 100;
Integer b = 100;
System.out.println(a == b); }
你可能会回答,这没什么不一样啊,所以还是false.很遗憾,如果你执行上面的一段代码,结果是true.
为什么会这样?现在我们分析一下上面的代码。可以很容易的看出,这一系列代码的最终目的都是用"=="对两个对象进行比较。Java中,如果用"=="比较两个对象结果为true,说明这两个对象实际上是同一个对象,false说明是两个对象。现在,我们来看看为什么会出现上面的现象。
我们先看代码片段4:最后的运行结果是true,说明a、b两个对象实际上是同一个对象。但是a对象是通过调用Integer的valueOf方法创建的,而b对象是通过自动装箱创建出来的,怎么会是同一个对象呢?难道问题在字节码那里,毕竟Java程序是依靠虚拟器运行字节码来实现的。
通过jdk中自带的工具javap,解析字节码,核心的部分摘取如下:
0: bipush 100 2: invokestatic #16; //Method java/lang/Integer.valueOf:(I)
Ljava/lang/Integer; 5: astore_1 6: bipush 100 8: invokestatic #16;
//Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 代码中我们只调用Integer.valueOf方法,但是字节码中出现了两次对Integer.valueOf方法的调用。那么另一次是哪里呢?只可能在自动装箱时调用的。因此这段代码实际上等价于:
public static void main(final String[] args) { Integer a = Integer.valueOf(100);
Integer b = Integer.valueOf(100);
System.out.println(a == b); }
现在问题就简单了:看jdk源代码,查看valueOf方法的具体实现:
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset]; }
return new Integer(i); }
看到这儿,上面的代码就很明确了:对于-128到127的数字,valueOf返回的是缓存中的对象。所以两次调用Integer.valueOf(100)返回的都是同一个对象。片段1和片段2就不做具体分析了,相信读者可以自行分析。
最后,请大家思考一下问题:通过上面的分析,了解到整数的自动装箱是通过Integer.valueOf
(int number)实现的,那么自动拆箱是如何实现的呢?
Java谜思解惑
精选 转载上一篇:取前1w个数据不超过4秒
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
“格物致知”的谜思
有幸加入了“得心研习社”的社群,希望能够得到一些国学的熏陶,进
格物致知 迷思 反思 参考资料 新知识 -
谜影
传说,在外太空有一个空间―五行域。在其中有个五行方阵,
空间 职场 情感 休闲 -
谜之复活。。。
米聊:我死了?骗你的。。。
微信 语音聊天 搜索 旧版 ios -
谜走点线_
。。
游戏 -
《java解惑》——类谜题
1.方法重载:
Test java System -
《java解惑》——库谜题
1.不可变类:
Test java System -
Elasticsearch 谜之null values
索引数据结构,它们根...
Elasticsearch 字段 搜索 显式
















