Java集合存取基本类型时自动装箱/拆箱:存入时调用Integer.valueOf()(-128~127缓存复用),取出赋值基本类型时调用intValue();需防null导致NPE及==比较陷阱。

Java 的自动装箱(autoboxing)和拆箱(unboxing)机制在集合(如 ArrayList、HashSet 等)中存取基本类型数据时,由编译器隐式完成转换,无需手动调用 Integer.valueOf() 或 .intValue()。但这个过程有明确的触发时机和潜在陷阱。
集合只能存对象,所以存基本类型时自动装箱
Java 集合框架(Collection 及其子接口)规定元素类型必须是引用类型(即对象),不能直接存 int、boolean 等基本类型。当你写:
ArrayList<Integer> list = new ArrayList<>(); list.add(100); // 编译器自动转为:list.add(Integer.valueOf(100))
这里 100 是 int 字面量,但 list.add() 参数要求 Integer,编译器在编译期插入装箱操作,等价于调用 Integer.valueOf(100)。
- 装箱不是每次新建对象:对于 -128 到 127 范围内的整数,
Integer.valueOf()返回缓存对象,提高性能 - 超出该范围(如
list.add(2000))会创建新Integer实例 - 其他包装类(
Boolean、Character、Long等)也有类似缓存策略,但范围不同
从集合取值时自动拆箱
当你从泛型集合中获取元素并赋给基本类型变量时,编译器自动插入拆箱逻辑:
立即学习“Java免费学习笔记(深入)”;
int value = list.get(0); // 编译器自动转为:list.get(0).intValue()
这行代码实际执行的是先拿到 Integer 对象,再调用其 intValue() 方法提取原始 int 值。
- 如果集合中存的是
null,而你直接拆箱(如int x = list.get(i)),运行时抛NullPointerException - 拆箱只发生在赋值给基本类型或参与算术/比较运算时(如
if (list.get(0) == 5)) - 若赋给包装类型(如
Integer i = list.get(0)),不发生拆箱
常见坑点:== 比较与 null 安全
自动装箱/拆箱让代码简洁,但也容易引发隐蔽错误:
-
Integer a = 128, b = 128; System.out.println(a == b); // false(不同对象) -
Integer c = 100, d = 100; System.out.println(c == d); // true(缓存复用) list.add(null); int x = list.get(0); // 抛 NPE- 建议统一用
.equals()比较包装类值,数值计算前检查是否为null
增强 for 循环和 Stream 中也适用
遍历集合时,自动转换同样生效:
for (int num : list) { ... } // 每次迭代自动拆箱
list.stream().mapToInt(Integer::intValue).sum(); // mapToInt 内部调用 intValue()
这些语法糖背后仍是编译器生成的装箱/拆箱字节码,语义清晰但需留意性能和空指针风险。


















