Integer缓存范围为-128至127,该范围内自动装箱复用对象使==返回true,范围外则新建对象使==返回false;应统一使用equals()比较值,避免引用误判。

Java 中 Integer 的自动装箱(autoboxing)看似简单,但背后隐藏着一个容易被忽视的缓存机制——它会让相同数值的 Integer 对象在某些范围内“相等”,超出范围则不等。这直接影响 == 比较的结果,是线上 bug 的常见源头。
Integer 缓存的默认范围是 -128 到 127
Java 在 Integer.valueOf(int) 方法中内置了缓存策略:对 -128 到 127(含)之间的整数,会复用已创建的 Integer 实例;超出该范围则每次新建对象。
- 这个范围由 JVM 参数
-XX:AutoBoxCacheMax=可调(如设为 200),但默认值固定为 127 - 缓存对象在类加载时初始化,存储在
Integer.IntegerCache.cache数组中 - 所有通过
valueOf()或自动装箱生成的Integer都走这个逻辑
自动装箱实际调用的是 valueOf(),不是 new Integer()
当你写 Integer a = 100;,编译器会将其翻译为 Integer a = Integer.valueOf(100);,而非 new Integer(100)(后者已废弃)。所以是否命中缓存,取决于数值是否落在 -128~127 内。
-
Integer a = 100; Integer b = 100;→a == b为 true(共用缓存对象) -
Integer c = 200; Integer d = 200;→c == d为 false(各自新建对象) -
Integer e = new Integer(100); Integer f = 100;→e == f为 false(new绕过缓存)
比较 Integer 应该用 equals(),而不是 ==
== 比较的是引用地址,而 equals() 会先判空再比较数值,安全且语义明确。
立即学习“Java免费学习笔记(深入)”;
- 即使两个
Integer值相同,用==也可能返回 false(如大数值或手动new) - IDE(如 IntelliJ)通常会对
==比较包装类发出警告 - 若需判断是否为同一对象(极少见),应明确注释意图,避免误读
其他包装类也有类似缓存,但范围不同
并非只有 Integer 有缓存。Java 对部分基本类型包装类做了类似优化:
-
Boolean:全部缓存(仅TRUE/FALSE两个实例) -
Byte、Short、Character(\u0000–\u007f,即 0–127):固定缓存,不可配置 -
Long和Float:valueOf()方法存在,但 无缓存实现(JDK 源码中未启用缓存数组)
理解 Integer 缓存机制不是为了背参数,而是为了避免把“碰巧相等”当成“理所当然”。写代码时统一用 equals(),既安全又省心。










