optional.or()提供延迟求值的备选optional生成器,返回optional类型;当前为空时执行supplier获取新optional,非空则直接返回自身,不触发supplier。

Optional.or() 的作用和基本用法
Optional.or() 不是提供一个默认值,而是提供一个“备选 Optional 生成器”——当调用它的对象为 empty() 时,才执行这个 Supplier 并返回其产生的 Optional。它和 orElse()、orElseGet() 的关键区别在于:返回类型仍是 Optional,且延迟求值。
- 它接收一个
Supplier<optional>></optional>,不是T或Supplier<t></t> - 如果当前
Optional非空,直接返回自身(不触发 Supplier) - 如果为空,才调用 Supplier,并返回它产出的
Optional(哪怕那个 Optional 也为空)
Optional<string> opt1 = Optional.empty();
Optional<string> opt2 = opt1.or(() -> Optional.of("fallback"));
// opt2 是 Optional["fallback"]
<p>Optional<string> opt3 = Optional.of("present");
Optional<string> opt4 = opt3.or(() -> {
System.out.println("never printed");
return Optional.empty();
});
// opt4 == opt3,且不会打印那行</string></string></p></string></string>
为什么不能直接传 Optional.of(...)?
常见错误是把 Optional.or() 当成 orElse() 的 Optional 版本,然后写成:
opt.or(Optional.of("fallback")) // ❌ 编译失败
因为 or() 要的是 Supplier<optional>></optional>,而 Optional.of(...) 是一个 Optional 实例,类型不匹配。必须用 lambda 或方法引用包装:
- ✅
opt.or(() -> Optional.of("fallback")) - ✅
opt.or(MyUtil::createFallback)(前提是createFallback()返回Optional<string></string>)
漏掉 lambda 括号会导致编译错误,这是新手最常卡住的地方。
和 orElseGet() 的核心差异在哪?
-
orElseGet(Supplier<t>)</t> 返回的是 T,会立即解包;一旦调用,你就失去了 “是否真有值” 的上下文
-
or(Supplier<optional>>)</optional> 返回仍是 Optional<t></t>,保留了空/非空语义,适合链式判断或后续组合
orElseGet(Supplier<t>)</t> 返回的是 T,会立即解包;一旦调用,你就失去了 “是否真有值” 的上下文or(Supplier<optional>>)</optional> 返回仍是 Optional<t></t>,保留了空/非空语义,适合链式判断或后续组合比如你想在 fallback 后再做一次 filter 或 map:
Optional<string> result = user.getNameOpt()
.or(() -> fetchFromCache())
.filter(s -> s.length() > 3)
.map(String::toUpperCase);
</string>
如果这里用了 orElseGet(),就得先转成 Optional.ofNullable(...) 才能继续链式调用,多一层包装且语义变弱。
容易被忽略的空安全陷阱
or() 的 Supplier 自身可以返回 Optional.empty(),这意味着“后备”也可能为空——整个链式结果仍可能是空:
Optional<string> opt = Optional.empty(); Optional<string> r = opt.or(() -> Optional.empty()); // r 仍是 empty </string></string>
所以不要默认认为 or(...) 一定能“兜住”空值。如果业务上要求最终必须有值,得额外处理:
- 接着调用
orElseThrow()或orElse("hardcoded") - 或改用两层 or:先 or 一个 fallback Optional,再 or 一个兜底的 non-null Supplier
真正复杂的场景里,or() 往往只是可选链中的一环,而不是终点。它价值在于延迟 + 类型保持,但不自动解决“空传播”问题。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











