Java 8+ 的 Optional.or() 用于空时通过 Supplier 生成新 Optional,正确写法是 optional1.or(() -> optional2);常见错误是误传 Optional 实例而非 Supplier;orElse/orElseGet 返回 T 类型值,而 or 返回 Optional,适合链式操作。

Java 8+ 的 Optional.or() 并不适用于“在第一个为空时切换到另一个可选数据源”这种常见场景——它实际作用是:当当前 Optional 为空时,执行一个 Supplier
很多人误以为可以这样写:
optional1.or(optional2) // ❌ 编译错误!因为 or() 的参数类型是 Supplier,不是 Optional。下面讲清楚怎么正确实现“空则 fallback 到另一个 Optional”的逻辑。
✅ 正确用法:用 lambda 包装后备 Optional
要让 optional1.or() 在为空时返回 optional2,需把 optional2 封装进 Supplier:
-
optional1.or(() -> optional2)—— ✅ 合法且简洁 - 注意:
optional2是立即求值的(非延迟),只要optional1为空就会被返回,不会重新计算 - 如果
optional2的获取开销大或有副作用,应改用Optional.ofNullable(...)或其他惰性方式构造
⚠️ 常见误区:和 orElse()、orElseGet() 混淆
or() 返回的是 Optional,而另外两个返回的是 T:
-
optional1.orElse(value)→ 直接返回T类型值(非 Optional) -
optional1.orElseGet(() -> computeValue())→ 同样返回T,但惰性求值 -
optional1.or(() -> Optional.of(computeValue()))→ 返回新的Optional,适合链式操作(如后续 flatMap、filter)
? 实用示例:从缓存 fallback 到数据库
假设你有两个数据源:
OptionalOptional
// 安全组合:有缓存用缓存,否则用 DB 结果
Optional
这样得到的 result 仍是 Optional,可继续调用 map()、ifPresent() 等,保持空安全风格。
? 进阶:多级 fallback(如缓存 → DB → 默认用户)
可链式调用 or():
.or(() -> db.findById(id))
.or(() -> Optional.of(defaultUser));
注意:每级 Supplier 都只在前一级为空时执行,天然支持短路。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











