orElseGet 在 Optional 为空时才延迟执行 Supplier 获取默认值,而orElse会立即执行参数表达式;适用于高成本默认值构造场景,避免无谓计算开销。

orElseGet 用于在 Optional 为空时,**延迟执行一个 Supplier 函数来生成默认值**,避免无谓的计算开销。
为什么用 orElseGet 而不是 orElse?
orElse 会**立即执行参数表达式**,即使 Optional 非空也照算;orElseGet 只在 Optional 为空时才调用 Supplier,真正实现“惰性”。
- ✅ 正确场景:默认值构造成本高(如数据库查询、文件读取、复杂对象初始化)
- ❌ 错误用法:写成
optional.orElse(new HeavyObject())—— 每次都创建,浪费资源 - ✅ 推荐写法:
optional.orElseGet(() -> createHeavyObject())—— 空时才调用
基本用法示例
假设从配置中读取超时毫秒数,缺失时返回默认值 3000:
Optional<Integer> timeoutOpt = getConfigValue("timeout");
int timeout = timeoutOpt.orElseGet(() -> {
System.out.println("使用默认超时值:3000");
return 3000;
});
如果 timeoutOpt 有值,System.out.println 不会执行;只有为空时才触发 Supplier 执行。
立即学习“Java免费学习笔记(深入)”;
与 orElse 的关键区别对比
看这段代码的实际输出:
Optional<String> opt = Optional.empty(); String s1 = opt.orElse(getDefaultString()); // 立即调用 getDefaultString() String s2 = opt.orElseGet(() -> getDefaultString()); // 仅在此处调用
若 getDefaultString() 打印日志或耗时操作,s1 会触发一次,s2 在 opt 为空时才触发——两者行为不同。
常见误用提醒
- 不要传入 null Supplier:会抛
NullPointerException - Supplier 内部不应有副作用依赖外部可变状态(影响可测试性和线程安全)
- 若默认值是常量且无开销(如字符串字面量),orElse 更简洁;否则优先选 orElseGet


















