Java自动拆箱不安全,null调用intValue()等方法直接抛NullPointerException;防御需避免拆箱操作执行到null上,如用Objects.equals、Integer.compare或Optional。

不会。Java自动拆箱本身不包含任何空指针安全检查,它只是编译器在字节码层面悄悄插入 xxxValue() 方法调用(如 intValue()、booleanValue()),而 null 对象调用这些实例方法会直接抛出 NullPointerException。
自动拆箱在哪一刻失败?
不是在“判断是否为空”时失败,而是在执行拆箱动作的瞬间失败——也就是 JVM 尝试调用 null.intValue() 这一行字节码执行时,立刻崩溃。堆栈里清晰显示 Integer.intValue 或 Boolean.booleanValue,说明问题就出在这里,而非你写的 if 判断逻辑之后。
哪些写法看似安全实则危险?
以下代码都因类型推断或上下文需要基本类型,导致编译器强制插入拆箱,且前面的判空挡不住后面的拆箱调用:
-
Integer a = null; if (a != null && a > 0) { ... }→a > 0触发a.intValue(),NPE -
Double d = null; double x = d + 1.0;→d.doubleValue()被调用,NPE -
Boolean flag = null; return flag ? "yes" : "no";→ 编译器将整个表达式定为boolean类型,flag必须拆箱,NPE -
Map<String, Integer> map = ...; int v = map.get("missing");→get()返回null,赋值给int即触发拆箱,NPE
真正有效的防御方式
核心原则是:不让拆箱操作执行到 null 上,而不是指望 JVM 帮你拦住它:
立即学习“Java免费学习笔记(深入)”;
- 比较相等性用
Objects.equals(a, b),它内部先判空,不拆箱 - 大小比较用
Integer.compare(a, b) >= 0,传入null会返回确定值(如 -1),不调用intValue() - 取默认值优先走
Optional.ofNullable(x).orElse(0)或NumberUtils.toInt(x, 0) - 方法参数若需基本类型,调用前显式校验:
if (x != null) process(x);,或干脆把参数类型改为Integer
别被 IDE 提示误导
IntelliJ 可能标黄 “Boxing/unboxing may occur”,但这只是提醒有语法糖存在,不代表它会帮你加 null 检查。真正的空安全必须由你主动编码实现,比如把 if (status == 1) 改成 if (Objects.equals(status, 1)),这才是落地的防护。


















