optional.orelsethrow() 可封装空值校验逻辑,实现语义清晰、类型安全的统一异常处理;配合工具类和supplier可支持错误码、动态参数与全局捕获,但仅适用于简单存在性校验,不适用于复杂业务规则。

用 Optional.orElseThrow() 构建统一变量校验异常处理机制,核心在于把“空值检查 + 异常抛出”这一高频逻辑封装成可复用、语义清晰、类型安全的校验表达式,避免零散的 if (obj == null) 和重复的 throw new XxxException()。
用 orElseThrow 替代冗余判空 + 手动 throw
传统写法容易分散、不易维护:
if (user == null) {
throw new IllegalArgumentException("用户不能为空");
}
if (user.getId() == null) {
throw new IllegalArgumentException("用户ID不能为空");
}
换成 Optional 链式调用后,语义更紧凑,且天然支持函数式异常构造:
Optional.ofNullable(user).orElseThrow(() -> new BusinessException("用户不存在"))Optional.ofNullable(user.getId()).orElseThrow(() -> new BusinessException("用户ID缺失"))
封装通用校验工具方法,提升复用性
为避免每个地方都写 Optional.ofNullable(...).orElseThrow(...),可封装静态工具方法:
Check.notNull(obj, "订单ID") → 抛出带字段名的业务异常Check.notBlank(str, "用户名") → 先判 null 再判 blank- 内部统一使用
Optional.ofNullable(...).orElseThrow(...)实现,保证底层一致
这样既保留了 orElseThrow 的简洁性,又屏蔽了模板代码,调用端更干净:
User user = Check.notNull(getUserById(id), "用户查询结果"); String name = Check.notBlank(user.getName(), "用户名");
结合 Supplier 统一异常类型与错误码
业务系统通常要求异常携带错误码(如 ERR_USER_NOT_FOUND)和上下文参数。利用 orElseThrow(Supplier) 可延迟构造异常,轻松注入动态信息:
Optional.ofNullable(user).orElseThrow(() -> new BusinessException(ErrCode.USER_NOT_FOUND, "id=%s", id))- 异常类支持格式化构造,错误码 + 消息模板 + 参数,日志和前端提示更精准
- 所有校验点最终抛出同一种异常基类(如
BusinessException),便于全局统一捕获和处理
注意边界:不适用于复杂校验逻辑
orElseThrow 适合“非空即错”的简单断言,不适合含多条件、跨字段、需查库或远程调用的校验:
- ✅ 适合:
user != null、order.getStatus() != null、StringUtils.hasText(email) - ❌ 不适合:
用户邮箱是否已注册、订单金额是否超过信用额度、密码强度是否符合策略 - 复杂校验仍应走独立 Service 方法,保持职责清晰;
Optional校验只负责“存在性”和“基础合法性”










