原: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. hihocoder 1485----hiho字符串

    hihocoder 1485:hiho字符串 描述 如果一个字符串恰好包含2个'h'.1个'i'和1个'o',我们就称这个字符串是hiho字符串. 例如"oihateher".&q ...

  2. FineReport中JS如何自定义按钮导出

    FineReport支持多种不同的导出方式,直接使用FineReport内置导出按钮可以非常快捷方便的来对各种格式的输出,但是我们在web页面集成中的时候,往往只想将报表内容嵌入到iframe中,而工 ...

  3. Ubuntu中网络配置interfaces与界面网络配置NetworkManager

    [Server版本] 在Ubuntu Server版本中,因为只存有命令行模式,所以要想进行网络参数设置,只能通过修改 /etc/network/interfaces .具体设置方法如下: (1) U ...

  4. 拖拽进度条(SeekBar)

    拖拽进度条(SeekBar) 监听方法:setOnSeekBarChangeListener 监听器:SeekBar.OnSeekBarChangeListener 简单,直接上代码: 1.Activ ...

  5. 填报表导出excel非可写单元格锁定问题

     问题描述: 填报表单元格分为可写和不可写两种状态,当填报表在web上展现的时候可写单元格可以进行数据填报和修改,非可写单元格不可操作. 报表导出为excel时,润乾导出excel包默认情况下不对 ...

  6. 带你从零学ReactNative开发跨平台App开发[expo 打包发布](八)

    ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...

  7. Jboss的jmx-console中查看内存和线程状态

    步骤: 1.假设jboss运行在 192.168.1.100:8080 地址和端口上. 2. 浏览器中访问http://192.168.1.100:8080/,然后选择jmx-console 3.选择 ...

  8. VisualSVN Server迁移的方法

    VisualSVN Server迁移涉及到两种情况: 第一种情况:VisualSVN Server没有更换电脑或者服务器,只是修改Server name. 第二种情况:当VisualSVN Serve ...

  9. django中的权限控制(form增删改)

    Django默认提供了权限控制,但只能对使用了其自带的登录认证的用户进行权限控制,说白了就是只能对存储在auth_user表中的用户进行权限控制,但不能对未登录过的用户进行权限控制.但如果通过集成LD ...

  10. Oracle重启操作步骤

    有时候在服务中重启了oracle之后,数据库并不能正常访问,可以通过以下步骤: 在windows服务中启动数据库服务: 在windows命令窗口中输入命令:sqlplus /nolog 在sql> ...