不推荐用 try-catch 处理 nullpointerexception,因其是编程错误,应通过主动防御(如参数校验、optional、判空)预防;仅极少数外部边界场景可捕获,且不可用于业务恢复。

Java 经典业务中,不推荐用 try-catch 捕获 NullPointerException(NPE)来处理空指针。这不是“怎么用”,而是“不该用”——因为 NPE 是 RuntimeException,属于编程错误,应通过预防而非捕获来解决。
为什么不该用 try-catch 处理空指针
空指针异常本质是逻辑缺陷:变量本该有值却为 null,说明前置校验缺失、接口契约未遵守、或状态管理混乱。用 try-catch 掩盖它,会导致:
- 掩盖真实 bug,让问题延迟暴露甚至被忽略
- 异常处理开销大,影响性能(尤其高频调用场景)
- 堆栈信息模糊,难以定位 null 的源头(是参数?返回值?还是中间对象?)
- 业务逻辑与错误处理混杂,代码可读性和可维护性下降
正确做法:主动防御,杜绝空指针
在业务代码中,应把精力放在“不让 null 出现”和“明确 null 含义”上:
-
方法入参校验:用
Objects.requireNonNull(param, "xxx 不能为空")或 Spring 的@NotNull+@Valid -
返回值约束:集合返回
Collections.emptyList()而非 null;对象返回 Optional(如Optional<user> findUser(id)</user>) -
链式调用前判空:用
Objects.nonNull(obj)或 Java 8+ 的obj?.method()(需用 Lombok @NonNull 或 IDE 提示辅助) -
数据库层约定:MyBatis/MyBatis-Plus 配置
mapUnderscoreToCamelCase=true和空值处理器,避免字段映射为 null
极少数可接受 try-catch 的场景
仅限于你完全无法控制的外部边界,且 null 行为已明确定义:
- 调用遗留系统或第三方 SDK,文档明确写“可能返回 null,需自行判空或捕获 NPE”(罕见,应推动对方改进)
- 解析动态 JSON(如 Jackson
ObjectMapper.readValue()后强转),但更优解是用泛型 +@JsonInclude(NON_NULL)或自定义反序列化器 - 日志兜底:在顶层全局异常处理器中记录未捕获的 NPE(用于监控告警),但绝不用于业务恢复逻辑
一个典型业务对比示例
❌ 错误示范(靠 catch 救火):
try {
String name = user.getAddress().getCity().toUpperCase();
} catch (NullPointerException e) {
log.warn("用户地址信息不全,使用默认城市");
name = "北京";
}
✅ 正确写法(预防为主):
String name = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.map(String::toUpperCase)
.orElse("北京");
或者更清晰的分步判空(适合复杂逻辑):
if (user != null && user.getAddress() != null && user.getAddress().getCity() != null) {
name = user.getAddress().getCity().toUpperCase();
} else {
name = "北京";
}
不复杂但容易忽略:空不是状态,是缺失。业务代码里每个 null 都该有明确理由,而不是靠异常兜底。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











