Java自动装箱调用Integer.valueOf()并依赖-128~127缓存池,故Integer a=100,b=100时a==b为true;而c=200,d=200时c==d为false;拆箱(如int x=a)始终调用intValue(),不涉缓存。

Java 自动装箱与拆箱和 Integer 缓存池是紧密耦合的机制,它们共同作用于编译期转换和运行时对象复用。关键在于:自动装箱实际调用的是 Integer.valueOf(),而这个方法内部就依赖缓存池;自动拆箱则不受缓存影响,只调用 intValue()。
自动装箱触发缓存池逻辑
当你写 Integer a = 100;,编译器会转成 Integer a = Integer.valueOf(100);。而 valueOf() 的实现是:
- 若传入值在 -128 到 127(含)范围内,直接返回缓存数组中已有的 Integer 对象;
- 超出该范围,每次都会 new 一个新对象,不复用。
所以 Integer a = 100; Integer b = 100; 中,a == b 返回 true;但 Integer c = 200; Integer d = 200; 中,c == d 返回 false——这不是语法糖的问题,而是缓存是否命中决定的。
自动拆箱绕过缓存,只取值
拆箱过程完全不涉及缓存判断。例如:
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
int x = a;→ 编译为int x = a.intValue();,无论 a 是缓存对象还是 new 出来的,都只取其内部 int 值; - 混合运算如
Integer p = 100; int q = p + 5;,p 先自动拆箱为 int,再参与加法,缓存与否对结果无影响。
== 比较时的典型陷阱
这是缓存与装箱结合后最容易出错的场景:
-
Integer a = 127; Integer b = 127;→a == b为 true(缓存命中); -
Integer c = 128; Integer d = 128;→c == d为 false(各自 new); -
Integer e = 128; int f = 128;→e == f为 true(e 自动拆箱后比较数值)。
注意:只要出现基本类型参与比较,JVM 就强制执行拆箱,此时 == 变成数值比较,不再有引用歧义。
泛型与集合中的隐式依赖
像 ArrayList<integer></integer> 这类结构必须使用包装类,添加元素时会发生自动装箱:
-
list.add(42);→ 实际调用list.add(Integer.valueOf(42));; - 42 在缓存范围内,因此多次 add(42) 得到的其实是同一个 Integer 实例(可被 GC 优化复用);
- 但
list.add(1000);每次都新建对象,可能带来轻微堆压力。
这说明缓存机制在高频装箱场景(如循环插入小整数)中能真实降低对象创建开销。

















