1. 概述
包装类本质上是对 Java 基本类型的对象封装。每个基本类型都有对应的包装类:
- 基本类型:
boolean
,byte
,short
,char
,int
,long
,float
,double
- 包装类:
Boolean
,Byte
,Short
,Character
,Integer
,Long
,Float
,Double
这些类都定义在 java.lang
包中,无需手动导入。
2. 包装类的核心价值
"包装类到底有啥用?" 这绝对是Java面试高频问题。简单粗暴地说:
✅ 泛型只支持对象,不兼容基本类型
以集合框架为例,在 Java 5 之前(大概15年前)还没有自动装箱机制,像 ArrayList<Integer>
这种集合直接调用 add(5)
是会报错的。当时必须手动将基本类型转换为包装类:
// Java 5 之前的写法
list.add(Integer.valueOf(5));
现在虽然可以用 list.add(101)
,但底层仍然是通过 valueOf()
方法转换为 Integer
对象后再存入集合。
3. 基本类型与包装类的转换
如何把基本类型转成包装类?有两种方式:
⚠️ 构造器方式(已废弃)
Integer obj = new Integer(1); // Java 9+ 已废弃
✅ 静态工厂方法(推荐)
Integer obj = Integer.valueOf(1);
valueOf()
方法有两个优势:
- 缓存优化:默认缓存 -128 到 127 的值
- 性能更高:超出缓存范围时也会复用已有实例
其他类型转换同理:
Boolean boolObj = Boolean.valueOf(true);
Character charObj = Character.valueOf('a');
反向转换(包装类→基本类型)使用 xxxValue()
方法:
int val = obj.intValue(); // 拆箱为 int
double dVal = doubleObj.doubleValue(); // 拆箱为 double
📌 特殊情况:String 不是包装类,转 Integer 需用
parseInt()
而非valueOf()
4. 自动装箱与拆箱
Java 5 引入的自动装箱(Autoboxing)和自动拆箱(Unboxing)让转换更丝滑:
4.1 自动装箱
List<Integer> list = new ArrayList<>();
list.add(1); // 自动装箱:int → Integer
Integer val = 2; // 等价于 Integer.valueOf(2)
4.2 自动拆箱
Integer obj = Integer.valueOf(1);
int num = obj; // 自动拆箱:Integer → int
int result = getSquareValue(obj); // 方法参数自动拆箱
public static int getSquareValue(int i) {
return i * i;
}
⚠️ 性能陷阱
自动装箱虽然方便,但在循环中可能引发性能问题:
// 反例:循环内频繁装箱
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i; // 每次循环都创建新 Long 对象
}
5. 总结
特性 | 说明 |
---|---|
本质 | 基本类型的对象封装 |
核心价值 | 使基本类型能用于泛型/集合等面向对象的场景 |
转换方式 | 优先用 valueOf() (构造器已废弃) |
自动机制 | 装箱(基本→对象)和拆箱(对象→基本)在 Java 5+ 自动完成 |
最佳实践 | 循环/高频操作中避免自动装箱,优先使用基本类型 |
掌握包装类是写出高质量 Java 代码的基础,尤其在集合操作和泛型场景中至关重要。