什么是自动拆箱装箱?
答案
定义
- 自动装箱(Autoboxing):
- 将基本数据类型(如
int
)自动转换为对应的包装类(如Integer
)。 - 自动拆箱(Unboxing):
- 将包装类(如
Integer
)自动转换为对应的基本数据类型(如int
)。
原理
- Java 编译器在 JDK 1.5+ 引入,自动调用包装类的
valueOf()
(装箱)和xxxValue()
(拆箱)方法。
作用
- 简化代码,方便基本类型与对象类型互用(如集合中使用
Integer
)。
1. 自动拆箱/装箱详解
(1) 基本类型与包装类
基本类型 | 包装类 |
---|---|
int | Integer |
double | Double |
boolean | Boolean |
char | Character |
... | ... |
(2) 自动装箱
- 过程:
int
->Integer
,调用Integer.valueOf(int)
。- 示例:
int a = 10;
Integer b = a; // 自动装箱
// 编译器转为:Integer b = Integer.valueOf(a);
(3) 自动拆箱
- 过程:
Integer
->int
,调用Integer.intValue()
。- 示例:
Integer x = 20;
int y = x; // 自动拆箱
// 编译器转为:int y = x.intValue();
(4) 混合使用
- 运算:
Integer a = 10; // 装箱
int b = 20;
int c = a + b; // a 拆箱,运算后仍是 int
- 集合:
List<Integer> list = new ArrayList<>();
list.add(5); // 自动装箱为 Integer
int value = list.get(0); // 自动拆箱为 int
2. 源码视角
Integer.valueOf()(装箱)
public static Integer valueOf(int i) {
if (i >= -128 && i <= 127) // 缓存池
return IntegerCache.cache[i + 128];
return new Integer(i);
}
intValue()(拆箱)
public int intValue() {
return value; // 返回内部 int 值
}
缓存机制
- 范围:
-128
到127
。 - 效果:小整数复用对象,节省内存。
- 示例:
Integer a = 100; // 装箱,缓存
Integer b = 100;
System.out.println(a == b); // true
Integer c = 200; // 装箱,新对象
Integer d = 200;
System.out.println(c == d); // false
3. 注意事项
(1) NullPointerException
- 问题:
Integer
为null
时拆箱抛异常。- 示例:
Integer i = null;
int j = i; // NullPointerException
(2) 性能开销
- 装箱:创建对象,增加内存和 GC 负担。
- 拆箱:调用方法,略慢于直接操作
int
。 - 建议:
- 高性能场景用
int
,集合用Integer
。
(3) 比较陷阱
==
:- 比较
Integer
对象地址,缓存影响结果。 equals
:- 比较值,需拆箱。
- 示例:
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true(缓存)
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false(新对象)
4. 延伸与面试角度
- 引入背景:
- JDK 1.5 前需手动装箱(如
Integer i = new Integer(10)
)。 - 适用场景:
- 装箱:集合、泛型。
- 拆箱:运算、赋值。
- 实际应用:
List<Integer>
存储数字。- 方法参数传递。
- 面试点:
- 问“定义”时,提
valueOf
和intValue
。 - 问“问题”时,提 NPE 和缓存。
总结
自动装箱是将基本类型转为包装类,拆箱反之,由编译器自动实现。简化代码但需注意 null 和性能。面试时,可提缓存范围或举 NPE 示例,展示理解深度。