如何向女朋友解释int==Integer为true
原: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); }
总结
了解原理是弄清问题的关键,像这样的问题以后还多着呢。不懂的时候可以敲敲代码,然后反编译,看看虚拟机是怎么处理的,看看原理翻翻源码,问题也就迎刃而解了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?