应使用 equals() 或 objects.equals() 比较包装类值,而非 ==;因 == 比较内存地址,受缓存机制影响不可靠;自动拆箱时 int 与 integer 可用 ==,但需防 null。

别用 == 直接比较包装类对象的值——它比的是内存地址,不是数值大小。缓存机制(比如 IntegerCache)只是让某些情况下 == “碰巧”为 true,但这不可靠、不安全、也不该被依赖。
缓存机制只影响对象创建,不影响比较语义
Java 的 Integer 等包装类通过 valueOf() 方法复用 -128 到 127 范围内的对象实例,这是为了节省内存和减少 GC 压力。但这个机制本身不是为“方便 == 比较”设计的:
-
Integer a = 127; Integer b = 127;→a == b为true(共用缓存对象) -
Integer c = 128; Integer d = 128;→c == d为false(各自新建对象) -
Integer e = new Integer(127); Integer f = 127;→e == f一定为false(new绕过缓存)
真正安全的值比较方式
无论是否在缓存范围内、无论怎么创建对象,以下写法都稳定可靠:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
优先用
equals():如a.equals(b)。它内部先判类型再比数值,已处理null和类型不匹配;若不确定左操作数是否为空,改用Objects.equals(a, b) -
转基本类型后比较:如
a != null && b != null && a.intValue() == b.intValue(),适合已知非空且追求轻微性能优势的场景 -
用
compareTo() == 0:语义明确,支持排序延伸,配合Objects.compare(a, b, Comparator.naturalOrder())可安全处理null
和基本类型比较时可以放心用 ==
当一边是 int,另一边是 Integer 时,JVM 会自动拆箱(调用 intValue()),此时 == 实际比较两个 int 值:
-
int i = 128; Integer j = 128;→i == j为true - 但
Integer k = null;时,i == k会抛NullPointerException,务必提前判空
缓存范围不是铁律,而是可调的 JVM 行为
默认 -128 ~ 127 是规范强制要求,但上限可通过启动参数调整:
-
-XX:AutoBoxCacheMax=200:让Integer.valueOf(180)也命中缓存 -
-Djava.lang.Integer.IntegerCache.high=250:效果类似,部分 JDK 版本支持 - 注意:扩大缓存会增加常驻堆内存,低配环境慎用;下限 -128 固定不可调
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










