Java中==对小整数有效大整数无效的原因及最佳实践
Java中Integer使用==比较的特殊行为解析
你遇到的这个现象,核心原因是Java对小范围Integer对象做了缓存优化,导致自动装箱时,不同变量可能指向同一个对象,而超出范围的则会创建新对象。
示例代码
Integer a = 127; Integer b = 127; System.out.println(a == b); // Output: true
Integer c = 128; Integer d = 128; System.out.println(c == d); // Output: false
差异原因
==运算符比较对象时,判断的是两个变量是否指向内存中的同一个对象(引用相等性)。而Java为了减少内存开销、提升性能,对**-128到127**范围内的Integer对象做了缓存:当通过自动装箱(比如直接赋值Integer x = 127)或者调用Integer.valueOf()方法创建对象时,会直接复用缓存池里已存在的对象,所以a和b指向同一个实例,==返回true;而128超出了默认缓存范围,每次都会创建新的Integer对象,c和d的引用不同,==返回false。
底层处理逻辑
这个缓存逻辑实现在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); }
其中IntegerCache.low固定为-128,IntegerCache.high默认是127,这个上限可以通过JVM启动参数-XX:AutoBoxCacheMax=<size>手动调整,但下限无法修改。当类加载时,IntegerCache会预先创建好-128到high之间的所有Integer对象,存放在数组中供后续复用。
比较Integer的最佳实践
- 优先使用
equals()方法:Integer类重写了equals()方法,会直接比较两个对象底层的int数值,不受缓存影响,能准确判断数值是否相等:System.out.println(c.equals(d)); // Output: true - 如果是原始类型int,直接用
==:如果变量是int类型,==就是比较数值,不存在引用问题,无需担心缓存影响。 - 不要依赖缓存行为做引用比较:缓存范围可能因JVM参数调整而变化,依赖它会导致代码健壮性下降,始终以数值相等性作为比较目标。
内容的提问来源于stack exchange,提问作者YAS -SER
相关产品推荐
相关产品推荐

