原:https://juejin.im/post/5c7f3cb25188251b883cada2

int==Integer为什么返回true

先看现象吧

执行下面的代码及输出结果:

int a = 1;
Integer b = 1;
Integer c = new Integer(1);
System.out.println(a==b);//true
System.out.println(a==c);//true
System.out.println(b==c);//false

通常大家对此的解释是,对于基本类型来说比较的是值,对于引用类型来说比较的是引用,即指向的对象的内存地址。这样解释没错,bc结果为false毋庸置疑,因为两个都是引用类型。但是为什么ab(ac)一个是基本类型一个是引用类型,比较的时候还是值比较呢?

这个时候我们不妨把.java源文件编译后的.class文件使用反编译工具反编译成源码,看看虚拟机内部是如何处理a==b的。

.class文件使用jd-gui反编译后的:

int a = 1;
Integer b = Integer.valueOf(1);
Integer c = new Integer(1);
System.out.println(a == b.intValue());
System.out.println(a == c.intValue());
System.out.println(b == c);

看到这想必大家都明白了吧,其实基本类型a和引用类型b比较时,引用类型b调用自身的intValue()方法获取Integer实际表示的int类型的值,即a == b.intValue()还是两个int类型的变量进行值比较。符合上述:==对于基本类型来说比较的是值,对于引用类型来说比较的是引用,即指向的对象的内存地址。

基本类型及引用类型在内存中的存储方式

说到这,还要解释下为什么两个引用类型的值一样而引用不一样以及基本变量为什么是值比较。

其实基本变量int a在内存里只有一份,保存在栈(保存基本类型的变量数据及引用类型的引用)中,Integer b和Integer c中的int值都指向栈中同一个int,不会重新在栈中创建相同的int值。

而对于Integer b和Integer c,其实例是保存在堆(保存所有new出来的对象)中,虽然表示的int值相同,但是在堆中有两份,每次new都会在堆中开辟一片空间保存new的内容,故Integer b和Integer c分别在两片不同的内存空间存储,所以指向的内存地址不同。

[]

而对于Integer b = 1;其反编译后为Integer b = Integer.valueOf(1);

而valueOf()方法内部是调用了new。

JDK中Integer.valueOf()源码:

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

总结

了解原理是弄清问题的关键,像这样的问题以后还多着呢。不懂的时候可以敲敲代码,然后反编译,看看虚拟机是怎么处理的,看看原理翻翻源码,问题也就迎刃而解了。


如何向女朋友解释int==Integer为true的更多相关文章

  1. 面试题:基础数据类型 包装类 int Integer

    因为在学习集合时知道集合里存放的对象都是Object类型,取出的时候需要强制类型转换为目标类型(使用泛型集合不需要),如int a = (Integer)arrayList.get(0):然后我们就会 ...

  2. Caused by: java.lang.IllegalArgumentException: Modifying queries can only use void or int/Integer as return type!

    Caused by: java.lang.IllegalArgumentException: Modifying queries can only use void or int/Integer as ...

  3. java中String,int,Integer,char、double类型转换

    java中String,int,Integer,char.double类型转换----https://www.cnblogs.com/kangyu222/p/5866025.html

  4. 漫话:如何给女朋友解释什么是"锟斤拷"?

    漫话:如何给女朋友解释什么是"锟斤拷"? ​ 周末女朋友出去逛街了,我自己一个人在家看综艺节目,突然,女朋友给我打来电话. 过了一会,女朋友回来了,她拿出手机,给我看了她在超市拍的 ...

  5. Java探秘之基本数据类型和包装类(int,Integer)(一)

    最近闲来无聊打算做一个博客网,没事记记笔记什么,可是网站不好做,需要点时间,就先写写笔记来练练手. 可是要写什么呢,太难的好像我也写不出来,万一写错了误导别人就不好了. 哈哈,不多说,直奔主题,要是写 ...

  6. java面试基础题------》int Integer Integer.valueOf

    在jdk1.5的环境下,有如下4条语句: 1 2 3 4 Integer i01 = 59; int i02 = 59; Integer i03 =Integer.valueOf(59); Integ ...

  7. 关于int,integer初始值问题

  8. TINYINT,SMALLINT,MEDIUMINT,INT,INTEGER,BIGINT;text,longtext,mediumtext,ENUM,SET等字段类型区别

    http://www.path8.net/tn/archives/951 MySQL支持大量的列类型,它可以被分为3类:数字类型.日期和时间类型以及字符串(字符)类型.本节首先给出可用类型的一个概述, ...

  9. (转载)MySQL数据类型:TINYINT, SMALLINT, MEDIUMINT, INT, INTEGER等字段类型区别

    (转自http://3y.uu456.com/bp-f088f739376baf1ffc4fad40-1.html) MySQL支持大量的列类型,它可以被分为3类:数字类型.日期和时间类型.字符串(字 ...

随机推荐

  1. Jquery插件网站持续添加。。。

    Look Fro Less,Do More www.jq22.com

  2. 卷积神经网络(CNN)在语音识别中的应用

    前言 总结目前语音识别的发展现状,dnn.rnn/lstm和cnn算是语音识别中几个比较主流的方向.2012年,微软邓力和俞栋老师将前馈神经网络FFDNN(Feed Forward Deep Neur ...

  3. Android 开发中三种多线程

    在开发工程中线程可以帮助我们提高运行速度,Android开发中我知道的线程有四个一个是老生长谈的Thread,第二个是asyncTask,第三个:TimetTask,第四个是Looper,四个多线程各 ...

  4. Oracle Sequence Cache 参数说明

    转自 http://blog.csdn.net/tianlesoftware/article/details/5995051 之前整理的一篇文章: ORACLE SEQUENCE 介绍 http:// ...

  5. lsnrctl 与 tnsnames.ora 的联系

    平台:Windoxs XP+Oracle 11G 当使用oralce的 Net Manager创建了一个名为“L3”的Listener后,要想使用lsnrctl启动和关闭 L3 还必须在tnsname ...

  6. 6.JXL操作Excel

    一.简介 jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一点.但jExcelA ...

  7. eclipse工具的安装配置

    安装环境 系统:Windows7 软件:jre-8u73-windows-x64.exe,eclipse-inst-win64.exe Eclipse的安装过程 1.安装jre-8u73-window ...

  8. The operation names in the portType match the method names in the SEI or Web service implementation class.

    The Endpoint validation failed to validate due to the following errors: :: Invalid Endpoint Interfac ...

  9. 如何添加设备UDID到开发者中心

    如何添加设备UDID到开发者中心 1. 登录开发者中心 2. 选择证书那一项 3. 选择Devices 4. 点选+按钮 5. 填上设备的UUID以及设备名字然后添加上 大功告成:) 附录: 如何获取 ...

  10. Linux strace命令详解

    Linux抓取TCP的命令: tcpdump ps -ef 参数命令详解: Linux下一切皆文件,我们打开一个socket,实际上也是打开了一个文件 我们打开一个网卡,实际上也是调用Linux系统的 ...