orElseThrow()需传入Supplier以延迟创建异常,空时才执行并抛出;正确写法为() -> new Exception("msg"),禁用new Exception()或throw语句,可链式调用结合map/flatMap。

直接用 optional.orElseThrow() 传入一个异常供应者(Supplier),就能抛出自定义异常。它不会立即创建异常对象,而是在 Optional 为空时才执行 Supplier,避免无谓的异常构造开销。
基本写法:传入 Lambda 表达式
最常用的方式是用 Lambda 创建一个新异常:
optional.orElseThrow(() -> new IllegalArgumentException("用户ID不能为空"))- 如果
optional是空的(empty()),才会执行 Lambda,抛出该异常 - 如果 Optional 有值,则直接返回该值,不触发异常构造
进阶写法:复用已有方法或封装逻辑
可以把异常创建逻辑提取成方法,提高可读性和复用性:
optional.orElseThrow(this::createUserNotFoundException)- 对应方法:
private RuntimeException createUserNotFoundException() { return new UserNotFoundException("未找到用户"); } - 适合异常信息需要动态拼接、查配置或加日志的场景
注意点:别直接 new 异常对象
下面这种写法是错的,会导致异常提前构造,失去延迟抛出的意义:
立即学习“Java免费学习笔记(深入)”;
- ❌
optional.orElseThrow(new IllegalArgumentException("xxx"))—— 编译不通过,类型不匹配 - ❌
optional.orElseThrow(() -> { throw new IllegalArgumentException("xxx"); })—— 语法合法但语义错误,这会立刻抛出异常,不是“空时才抛” - ✅ 正确姿势永远是 Supplier 返回异常实例,不 throw
常见搭配:和 map/flatMap 链式调用结合
在处理嵌套 Optional 或转换逻辑时,可以自然嵌入自定义异常:
userOptional.map(User::getProfile).map(Profile::getEmail).orElseThrow(() -> new IllegalStateException("用户资料或邮箱缺失"))- 只要中间任意一步为 null 或 Optional.empty(),最终就会抛出你指定的异常


















