java自动拆箱遇null必抛npe,修复关键是阻断null进入拆箱路径:运算/赋值前用三元表达式或objects.requirenonnullelse兜底;布尔判断用boolean.true.equals();集合取值先判空或用optional;比较统一用objects.equals。

Java 中自动装箱本身不危险,真正出问题的是自动拆箱时遇到 null —— 因为编译器会悄悄插入 intValue()、booleanValue() 这类方法调用,而 null 无法响应任何实例方法,必然抛 NullPointerException。修复的核心不是禁用装箱,而是切断 null 进入拆箱环节的路径。
运算和赋值前主动兜底默认值
所有可能为 null 的包装类参与算术运算、条件判断或赋值给基本类型前,必须显式处理空值。
- 用三元表达式提供安全默认值:
int value = (num != null) ? num : 0; - Java 9+ 推荐用
Objects.requireNonNullElse(num, 0),语义更清晰 - 数据库字段映射时,在 SQL 层用
COALESCE(amount, 0)或实体类字段加@Column(columnDefinition = "BIGINT DEFAULT 0")
布尔类型判断必须绕开自动拆箱
if (flag) 或 while (enabled) 这类写法,只要 flag 或 enabled 是 Boolean 类型且可能为 null,就一定会触发 booleanValue() 调用并崩溃。
- 安全写法是
if (Boolean.TRUE.equals(flag))——equals方法对null入参返回false,不会抛异常 - 若需区分
null、true、false三种状态,应改用枚举或明确的三态判断逻辑,避免依赖布尔包装类
集合与 Map 取值必须先校验再拆箱
List<integer></integer>、Map<string long></string> 等泛型集合中,元素或 value 为 null 是常见情况,但直接 list.get(i) + 1 或 map.get("key") > 0 就会立刻崩。
- 取值后立即判空:
Integer val = map.get("key"); if (val != null) { process(val); } - 用
Optional封装可空结果:Optional.ofNullable(map.get("key")).orElse(0L) - Map 的 key 使用数字类型时(如
Map<long v></long>),避免传入int字面量(如map.get(1)),防止因自动装箱成Integer导致匹配失败
比较操作统一用 Objects.equals
== 比较包装类不仅有缓存范围陷阱(-128~127),更会在一方为 null 时触发隐式拆箱。
- 一律改用
Objects.equals(a, b),它内部先判空再调用equals,对null安全 - 禁止写
status == 1,应写Objects.equals(status, 1)—— 后者等价于status != null && status.equals(1) - 涉及多个包装类字段联合判断时,优先提取为局部变量并集中判空,避免重复拆箱风险
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











