最直接预防空指针异常的方式是显式 null 检查,关键在于检查位置与方式:方法入口和构造函数用 Objects.requireNonNull() 校验必填参数;区分“可空/不可空”语义,善用 Optional 封装;借助 @NotNull 注解、Lombok 和静态分析工具辅助;返回值优先用空集合或 Optional 降低调用方风险。

Java 中空对象引用导致的空指针异常(NullPointerException)最直接的预防方式,就是显式做 null 检查——但关键不在于“要不要检查”,而在于“在哪儿检查、怎么检查更安全、更可维护”。
方法参数入口处尽早校验
对外暴露的方法(尤其是 public 方法)应第一时间确认入参是否为 null,避免问题向内传播。推荐使用 JDK 7+ 的 Objects.requireNonNull(),语义清晰且抛出的异常带提示信息:
-
Objects.requireNonNull(str, "字符串不能为空")—— 检查失败时抛出带消息的NullPointerException - 避免手写冗长的
if (obj == null) throw new NullPointerException(...),易遗漏或格式不统一 - 构造函数中对必填字段也应同样校验,确保对象创建即有效
业务逻辑中区分“可空”与“不可空”语义
不是所有变量都需要无脑判空。先明确设计意图:这个引用按契约本就不该为 null?还是它天然可能为空(如数据库查询结果、Map.get() 返回值)?
- 对于“不可空”场景(如已通过校验的成员变量),后续代码可直接调用,不必重复检查
- 对于“可空”场景(如
Optional.ofNullable(map.get("key")).orElse("default")),优先用Optional封装,把空值处理显式化、链式化 - 避免在多层嵌套调用中反复写
if (a != null && a.getB() != null && a.getB().getC() != null),可改用Optional.ofNullable(a).map(A::getB).map(B::getC).orElse(null)
利用现代工具减少手动检查负担
人工判空容易遗漏,借助工具可提前拦截:
立即学习“Java免费学习笔记(深入)”;
- IDE(如 IntelliJ)能基于 @NotNull / @Nullable 注解做静态检查,标红潜在风险点
- Lombok 的
@NonNull可自动生成构造/Setter 中的非空校验(注意:仅限于字段级,不替代业务逻辑判断) - 静态分析工具(如 SpotBugs)可扫描未处理的可能空值路径
- 单元测试中主动传入
null参数,验证是否被合理拦截或处理
返回值设计上减少调用方判空压力
方法提供者应尽量降低使用者踩坑概率:
- 集合类方法优先返回空集合(
Collections.emptyList())而非null - 工具类方法(如字符串处理)对
null输入有明确定义(如返回null或空字符串),并在 Javadoc 中写清 - 考虑用
Optional<T>作为返回类型,强制调用方意识到“可能没有值”,例如findUserById(id)返回Optional<User>而非User


















