== 比较 Integer 可能对或错,因 JVM 缓存 -128 至 127 的 Integer 实例;超出范围则新建对象;推荐用 equals()、intValue() 或 compareTo() 安全比较。

直接用 == 比 Integer,结果可能对、也可能错——这不是 bug,是缓存机制在“按规则出牌”。关键不在数值本身,而在它是否落在 JVM 默认缓存区间内。
缓存范围默认是 -128 到 127
Java 的 Integer.valueOf(int) 方法内部维护了一个静态缓存数组(IntegerCache.cache),对 -128 至 127(含)之间的整数,每次调用都返回同一个对象实例。超出该范围,则每次新建对象。
-
Integer a = 127; Integer b = 127;→a == b为 true(共用缓存对象) -
Integer c = 128; Integer d = 128;→c == d为 false(各自 new 出不同对象) - 该行为与编译器自动装箱强绑定:
Integer x = 100等价于Integer x = Integer.valueOf(100)
哪些写法会绕过缓存?
只要不走 valueOf(),就无法享受缓存红利。以下操作一律生成新对象,== 必为 false:
-
new Integer(100)—— 显式构造,堆中独立实例 -
Integer.parseInt("100")返回 int,再装箱时若值超限仍无缓存 - 反射调用构造器、序列化/反序列化后的对象
注意:Integer a = 100 和 Integer b = new Integer(100) 比较,a == b 一定是 false——前者指向常量池,后者指向堆。
安全比较的三种推荐方式
不依赖缓存、不惧 null、逻辑清晰才是生产级写法:
-
用
.equals()(最常用):重写了比较逻辑,先判类型再比值;但调用前需确保左操作数非 null,或改用Objects.equals(a, b) -
转基本类型再比:如
a != null && b != null && a.intValue() == b.intValue();适合已知非空场景,性能略优 -
用
compareTo() == 0:可处理 null(配合Objects.compare()),也适用于排序逻辑延伸
特殊场景:和 int 比较可以放心用 ==
当一边是基本类型 int,另一边是 Integer 时,JVM 自动触发拆箱(调用 intValue()),此时 == 实际比较的是两个 int 值:
-
int i = 128; Integer j = 128;→i == j为 true -
Integer k = null;→i == k会抛NullPointerException,务必先判空

















