解释为什么Java中“1000==1000”为false而”100==100“为true
作者:YSOcean
在日常编程中,我们经常遇到一些看似简单却隐藏着复杂逻辑的问题。
推荐阅读:
推荐Java微信公众号干货【Java技术迷】
【第19期】面试官:为什么 Java 中“1000==1000”为false,而”100==100“为true?
浅谈为什么Java中1000==1000为false而100==100为true
比如,你是否想过为什么在 Java 中表达式1000==1000
会返回 false,而 100==100
却返回 true 呢?
Integer a = 100; Integer b = 100; System.out.println(a == b); // 输出:true Integer c = 1000; Integer d = 1000; System.out.println(c == d); // 输出:false
1、源码追溯
解决问题,一定要深入本质,而解决编程问题,深入本质的方法就是对源码一探究竟。
可能大家不知道 Integer a = 100
这种代码是看哪个源码,不要紧,我们可以看下其编译后的 class 文件。
很明显,我们得看 Integer 类的 valueOf 方法:
继续看 IntegerCache :
为了防止大家不好理解,我这里为这个方法添加了详细注释:
private static class IntegerCache { // 缓存的下界值,固定为-128 static final int low = -128; // 缓存的上界值,可以通过系统属性进行配置 static final int high; // 缓存数组,用于存储从low到high范围内的Integer对象 static final Integer cache[]; static { // 默认情况下,缓存的上界是127 int h = 127; // 尝试从系统属性java.lang.Integer.IntegerCache.high中获取自定义的上界值 String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { // 将字符串转换为整数 int i = parseInt(integerCacheHighPropValue); // 确保自定义的上界至少为127,以包含Java规范要求的缓存范围 i = Math.max(i, 127); // 确保上界不超过Integer.MAX_VALUE - (-low) - 1,以防止数组大小超出Integer的最大值 h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // 如果字符串无法解析为整数,忽略该属性并保持默认的上界值 } } // 设置高界值 high = h; // 初始化缓存数组,数组大小根据low和high计算得出 cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) { // 创建Integer对象并填充数组 cache[k] = new Integer(j++); } // 断言确保缓存的上界至少为127,符合Java语言规范 assert IntegerCache.high >= 127; } // 私有构造器,防止外部实例化这个内部类 private IntegerCache() {} }
2、源码解读
其实这部分源码不难理解,首先对于 valueOf 方法,当传入的整型值在 -128-127 之间时,返回的是 IntegerCache 里面的值。
这个 IntegerCache 是在 Java 的 Integer 类中的一个内部静态类 ,它缓存了 -128 到 127 之间的整数。
当我们声明一个 Integer 对象并赋予一个在这个范围内的值时,Java 实际上会返回一个预先创建好的对象引用。
这种机制可以有效减少内存的使用,并提高性能。
3、解答问题
看懂了源码,在回到上面的问题,为什么表达式1000==1000
会返回 false,而 100==100
却返回 true 呢?
当我们使用 Integer
对象比较两个数时,实际上是在比较对象的内存地址。由于“100”在缓存范围内,两个“100”实际上引用的是同一个对象,所以返回 true。
相反,“1000”不在缓存范围内,即使数值相同,两个“1000”也是不同的对象,因此内存地址不同,返回 false。
4、正确比较
其实对于 Integer 这种包装类比较大小,我们应该使用 equals()
方法来比较两个 Integer
对象的数值,而不是直接使用 ==
操作符,除非我们确实想比较对象的引用。
Integer a = 100; Integer b = 100; System.out.println(a.equals(b)); // 输出:true Integer c = 1000; Integer d = 1000; System.out.println(c.equals(d)); // 输出:true
这点在阿里开发手册
中也有详细说明:
如果你是一名Java开发人员,我还是比较推荐你去阅读这个手册,对我们日常编码规范还是挺有帮助的。下面小编整理到网盘,喜欢的拿去用吧。
百度网盘下载链接
链接: https://pan.baidu.com/s/1gRmW6KIp1Re4Liwjf1y3_g
提取码: sb7t
到此这篇关于解释为什么Java中“1000==1000”为false而”100==100“为true的文章就介绍到这了,更多相关Java中“1000==1000”为false而”100==100“为true内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!