Java包装类缓存机制仅影响==比较结果,对equals()无影响;Integer等默认缓存-128~127,范围内==返回true,范围外或new创建则为false;所有值比较应统一用.equals()或Objects.equals()。

Java包装类的缓存机制本身不改变数值语义,只影响对象是否复用,因此它直接干扰的是==比较的结果,而对equals()完全无影响。理解这一点,就能避开绝大多数线上bug。
缓存让 == 比较结果变得“看值又看范围”
Integer等包装类通过valueOf()创建对象时,-128到127(含)范围内的值会复用同一个对象实例;超出该范围则每次新建对象。
-
在缓存范围内:如
Integer a = 127; Integer b = 127;→a == b为true(同一内存地址) -
超出缓存范围:如
Integer c = 128; Integer d = 128;→c == d为false(两个独立对象) -
手动 new 总是绕过缓存:哪怕值是100,
new Integer(100) == Integer.valueOf(100)也一定为false
equals() 始终可靠,因为它只比数值
Integer.equals()内部先校验类型和非空,再拆箱比较原始int值,与缓存无关。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
Integer.valueOf(127).equals(Integer.valueOf(127))→true -
Integer.valueOf(200).equals(Integer.valueOf(200))→ 同样true - 即使其中一个是
null,equals()也不会抛NPE(但==不会报错,只是逻辑错)
其他包装类的缓存行为差异
不是所有包装类都一样,实际使用中需注意边界:
立即学习“Java免费学习笔记(深入)”;
- Byte、Short、Long:默认也缓存-128~127,但不可配置
-
Character:只缓存\u0000~\u007F(即0~127),超出如
'ä'(U+00E4)不复用 -
Boolean:仅两个实例
TRUE/FALSE,本质是静态常量,==和equals()效果一致 - Float/Double:无缓存——浮点数精度和离散性使缓存失去意义
真正该做的不是记住数字,而是统一习惯
缓存范围(-128~127)只是一个实现细节,业务代码不该依赖它。正确姿势是:
- 所有包装类值比较,一律用
.equals(),或更稳妥地用Objects.equals(a, b) - 集合的key、Map查找、数据库ID匹配等场景,绝不用
==判断包装类相等 - 需要高性能且确定非null时,可先拆箱:
a.intValue() == b.intValue(),但前提是已确保a、b非null - 日志或调试中看到
==为true,不等于逻辑正确——它只是碰巧命中了缓存

















