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

因为自动拆箱本质是调用包装类的 xxxValue() 方法,而 null 对象无法调用任何方法。
拆箱不是“转换”,而是方法调用
当你写下:
Integer num = null;
int n = num;
Java 编译器实际把它翻译成:
int n = num.intValue();
这和写 num.toString() 或 num.hashCode() 没有本质区别——只要对象是 null,调用任意实例方法都会抛出 NullPointerException。
为什么装箱不会NPE,拆箱会?
自动装箱(如 int → Integer)底层调用的是 Integer.valueOf(int),这是一个静态方法,不依赖对象实例,所以传入基本类型值永远不会因 null 出错。
但自动拆箱(如 Integer → int)必须依赖已有对象来调用实例方法,一旦对象是 null,就直接触发 NPE。
哪些操作会悄悄触发拆箱?
- 与基本类型做算术运算: Integer a = null; int b = a + 1;
- 参与比较运算: if (status == 1) { ... }(status 是 null 的 Integer)
- 作为 return 值被赋给基本类型: public int getStatus() { return dbResult; }(dbResult 是 null)
- 三目运算中类型统一引发隐式拆箱: boolean flag = boolValue != null ? boolValue : false;(boolValue 是 null 的 Boolean)
怎么安全地绕过这个问题?
- 显式判空再取值:int n = (num != null) ? num : 0;
- 用 Objects.equals(a, b) 替代 == 比较包装类
- 优先使用基本类型参数/返回值,避免在 API 边界暴露包装类
- 数据库或 JSON 解析后,尽早将包装类转为带默认值的基本类型,别留着 null 到业务逻辑层

















