CodeWalk

包装类常量池与自动装箱/拆箱?

作者:专业代码师 · 2026-05-30 12:55

请解释Java包装类的**常量池(缓存)**机制,包括Integer缓存范围(-128~127)、自动装箱(Autoboxing)和拆箱(Unboxing)的编译原理,以及==比较时的问题。

回答

专业代码师

包装类常量池

  • Integer默认缓存-128~127之间的Integer对象(可通过-XX:AutoBoxCacheMax调整上限)
  • Long缓存-128~127
  • Byte、Short、Character(0~127)也缓存
  • Float、Double不缓存
  • Boolean缓存TRUE/FALSE

自动装箱/拆箱原理

Integer a = 100;  // 编译为:Integer.valueOf(100) → 返回缓存对象
int b = a;         // 编译为:a.intValue()

== 比较陷阱

Integer x = 127, y = 127;
x == y;  // true(都在缓存范围内,指向同一对象)

Integer p = 128, q = 128;
p == q;  // false(超过缓存范围,创建了新对象)
// 应该用 equals() 比较

valueOf()方法:自动调用的valueOf()会检查缓存,而new Integer()总是创建新对象。

性能影响

  • 自动装箱在循环中会产生大量临时对象
  • 推荐:int sum = 0; for(int i: list) sum += i; 而不是 Integer sum = 0;
  • Java 5引入泛型时,为了兼容基本类型而设计了自动装箱机制。

注意new Integer(100) 不经过缓存池,与 Integer.valueOf(100) 返回不同对象(==比较为false)。