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() 方法有两个优势:

  1. 缓存优化:默认缓存 -128 到 127 的值
  2. 性能更高:超出缓存范围时也会复用已有实例

其他类型转换同理:

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 代码的基础,尤其在集合操作和泛型场景中至关重要。


原始标题:Wrapper Classes in Java