orElseThrow是Optional中值为空时抛出异常的方法,支持Supplier创建异常(推荐)或复用已有异常对象(不推荐),可抛出任意Throwable子类,检查型异常需显式处理,核心用于强调“空值即错误”的契约校验。

orElseThrow 是 Optional 类中用于在值为空(Optional.empty())时抛出异常的方法。它支持两种重载形式:一种接收无参的异常 Supplier,另一种可传入自定义异常构造逻辑。
使用 Supplier 抛出自定义异常(推荐)
这是最常用的方式,通过 Lambda 或方法引用提供一个“异常生成器”,只有在值为空时才会执行,避免无谓的对象创建。
- 语法:
optional.orElseThrow(() -> new MyException("消息")) - 异常类型可以是任意
Throwable子类(如IllegalArgumentException、RuntimeException、或自定义检查/非检查异常) - 注意:Supplier 的 lambda 不带参数,只负责“创建并返回异常实例”
示例:
Optional<String> opt = Optional.empty();
String value = opt.orElseThrow(() -> new IllegalArgumentException("用户名不能为空"));
// 运行时抛出:java.lang.IllegalArgumentException: 用户名不能为空
复用已有异常对象(不推荐,仅限特殊场景)
如果异常对象已预先构建好(比如全局常量异常),可用无参重载版本:
立即学习“Java免费学习笔记(深入)”;
- 语法:
optional.orElseThrow(() -> MY_EXCEPTION) - 但需注意:该异常对象会被每次调用复用,若其状态可变(如含时间戳、堆栈等),可能引发意外行为
- 通常建议每次都新建异常,保证堆栈和上下文准确
抛出检查型异常(需处理或声明)
如果抛出的是检查型异常(如 IOException),调用处必须用 try-catch 或在方法签名中 throws 声明:
- 例如:
optional.orElseThrow(() -> new IOException("读取配置失败")) - 此时编译器会强制你处理该异常,不能忽略
-
orElseThrow的泛型会推断为该检查异常类型,方法签名需兼容
与 orElse 或 orElseGet 的对比要点
orElseThrow 的核心价值在于“空值即错误”,强调业务约束而非兜底逻辑:
-
orElse("default"):提供默认值,适合容错场景 -
orElseGet(() -> computeDefault()):延迟计算默认值,适合开销大时 -
orElseThrow(() -> new XxxException()):明确拒绝空值,适合契约性校验(如参数必填、查询结果必须存在)
用对 orElseThrow 能让代码意图更清晰,减少隐式 null 判断,也便于统一异常处理策略。


















