包装类常量池与自动装箱/拆箱?
请解释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)。