自动拆箱会触发 NullPointerException,因为其实质是调用包装类的实例方法(如intValue()),而null对象无法调用任何实例方法;装箱则调用静态方法valueOf(),不依赖实例,故不会NPE。

因为自动拆箱不是类型转换,而是方法调用——Java 编译器会把 int n = num;(其中 num 是 null 的 Integer)翻译成 int n = num.intValue();。而 null 对象无法调用任何实例方法,所以立刻抛出 NullPointerException。
拆箱的本质是调用 xxxValue() 方法
所有包装类的自动拆箱,底层都对应一个实例方法:
Integer → intValue()
Long → longValue()
Boolean → booleanValue()
Double → doubleValue()
这些方法必须由非空对象调用。一旦目标引用为 null,就像写 num.toString() 一样,JVM 直接拒绝执行并报 NPE。
哪些写法会悄悄触发拆箱?
你没写 .intValue(),但以下操作全都会隐式拆箱:
-
与基本类型比较:如
if (status == 1)(status是null的Integer) -
参与算术运算:如
int total = count + 10;(count为null) -
三目运算中类型统一:如
int result = flag ? 5 : value;(value是null的Integer) -
Stream 聚合操作:如
list.stream().mapToInt(x -> x).sum()(列表含null元素) -
直接赋值给基本类型变量:如
int age = user.getAge();(数据库字段为空时返回null)
为什么装箱不会 NPE,拆箱会?
自动装箱(如 int → Integer)调用的是静态方法 Integer.valueOf(int),不依赖对象实例,传入任意 int 值都不会因 null 出错;
而自动拆箱必须依赖已有对象来调用实例方法,对象一空,调用即断。
安全处理 null 包装类的常用方式
核心原则:别让 null 进入需要基本类型值的上下文。
- 显式判空再取值:
int safeAge = age != null ? age : 0; - 用
Objects.equals(a, b)替代==比较包装类 - 数据库/JSON 解析后立即转为带默认值的基本类型,不要把
Integer留在业务逻辑层 - API 接口尽量使用基本类型参数或返回值,避免暴露包装类
- 集合遍历时对元素判空:
total += score != null ? score : 0;

















