基本类型不能为null,无需判空;需判空的是包装类,未检查null即拆箱(如赋值、==比较、条件判断、算术运算)会触发NullPointerException;安全方式包括显式三元判断、Objects.requireNonNullElse(JDK9+)、Optional封装,且Boolean需用Boolean.TRUE.equals()避免隐式拆箱。

基本类型本身不能为 null,所以不存在“判空”概念;真正需要判空的是包装类(Integer、Long、Boolean 等)。一旦在未检查 null 的情况下参与拆箱操作,就会触发 NullPointerException。关键不是“怎么判”,而是“在哪判、为什么必须判、怎么判才安全”。
包装类哪些操作会悄悄拆箱并崩?
这些写法看着正常,但只要变量是 null,运行时立刻报错:
-
int value = integerObj;(赋值即拆箱) -
if (booleanObj) { ... }(条件判断隐式调用booleanValue()) -
int sum = a + b;(其中a或b是null的Integer) -
if (integerObj == 10)(==比较触发自动拆箱) -
map.get("key")返回null,直接赋给int变量
安全判空的三种主流方式
不依赖运气,用明确、可读、可复用的方式兜底:
-
显式三元判断:最直观,兼容所有 JDK 版本
int age = user.getAge() != null ? user.getAge() : 0; -
Objects.requireNonNullElse(JDK 9+):语义清晰,一行解决
int age = Objects.requireNonNullElse(user.getAge(), 0); -
Optional 封装:适合需链式处理或延迟决策的场景
int age = Optional.ofNullable(user.getAge()).orElse(0);
布尔包装类要特别小心
Boolean 是重灾区,因为 if (flag) 这种写法太常见。它不是语法糖,而是真实调用 flag.booleanValue():
立即学习“Java免费学习笔记(深入)”;
- ❌ 错误:
if (statusFlag) { ... }(statusFlag == null就崩) - ✅ 推荐:
if (Boolean.TRUE.equals(statusFlag)) { ... }(安全,不拆箱) - ✅ 或者:
if (Objects.nonNull(statusFlag) && statusFlag)
从源头减少 null 包装类
修复不如预防。让 null 尽可能不出现在业务逻辑层:
- 数据库映射时用
COALESCE(col, 0)或 MyBatis 的nullValue="0" - JSON 反序列化配置 Jackson 的
@JsonSetter(nulls = Nulls.SKIP)或设默认值 - DTO 字段加
@NotNull注解 + 参数校验拦截 - RPC 接口文档约定数值字段非空,服务端兜底返回默认值


















