java包装类null自动拆箱必抛nullpointerexception,须在拆箱前用objects.requirenonnull校验或optional封装可空语义,避免隐式拆箱操作,并从源头减少null包装类产生。

Java 中包装类(如 Integer、Boolean、Long 等)一旦为 null,在自动拆箱时必然触发 NullPointerException。这不是偶发问题,而是 JVM 对 null 调用 intValue()、booleanValue() 等方法的直接结果。避免的关键不是捕获异常,而是在拆箱动作发生前就阻断 null 流入。
拆箱前强制校验非空
使用 Objects.requireNonNull() 在解包前明确拦截 null,让错误暴露得早、定位得准:
-
✅ 正确写法:
int value = Objects.requireNonNull(obj, "obj must not be null").intValue(); -
❌ 错误写法:
int value = Objects.requireNonNull(obj).intValue();—— 校验发生在拆箱之后,无效 - 适用于方法入参、关键字段赋值等明确不允许
null的场景
用 Optional 封装可空语义
当值天然可能缺失(如数据库查询、API 返回),应主动用 Optional 表达这种不确定性,全程避免原始包装类暴露:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
✅ 安全取默认值:
int i = Optional.ofNullable(getCount()).orElse(0); -
✅ 链式过滤与转换:
opt.filter(x -> x > 100).map(x -> x * 2).ifPresent(System.out::println); - 不推荐
Optional.get(),应优先使用orElse、orElseGet或ifPresent
避开隐式拆箱的高危操作
这些看似简单的写法会在编译期悄悄插入拆箱调用,极易崩溃:
-
❌ 危险比较:
if (status == true)或if (count == 5)→ 改用Objects.equals(status, true)或Objects.equals(count, 5) -
❌ 危险运算:
total = amount + tax;(amount或tax为null)→ 改用(amount != null ? amount : 0) + (tax != null ? tax : 0) -
❌ 危险流操作:
list.stream().mapToInt(Integer::intValue).sum()→ 改用list.stream().filter(Objects::nonNull).mapToInt(Integer::intValue).sum()
源头防控:减少 null 包装类产生
与其处处防御,不如从设计上压缩 null 存活空间:
- 方法返回值优先用基本类型(如
int而非Integer),除非需区分“0”和“未设置” - DTO/VO 字段慎用包装类;必须用时,配合 Jackson 注解:
@JsonSetter(nulls = Nulls.AS_EMPTY)或@JsonInclude(NON_NULL) - MyBatis 映射 NULL 列时,在
resultMap中指定nullValue="0",或用@Options(defaultFetchSize = -1)配合自定义 TypeHandler - 集合类尽量用原始类型替代库(如 FastUtil 的
IntArrayList),彻底绕过包装类
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










