在Java 9之前,当我们处理Optional对象时,如果当前Optional为空,想要切换到另一个可选值产生器获取默认值,往往需要写多层判断或者复杂的逻辑分支,代码可读性较差。Java 9为Optional类新增的or方法,很好地解决了这个问题,支持通过流式调用的方式依次尝试不同的可选值产生器,实现灵活的默认可选值切换逻辑。

Optional.or() 方法的基本定义
Optional的or方法接收一个Supplier<? extends Optional<? extends T>>类型的参数,当当前Optional对象有值时,直接返回当前对象;如果当前对象为空,就会调用传入的Supplier获取新的Optional对象返回。方法签名如下:
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
Objects.requireNonNull(supplier);
if (isPresent()) {
return this;
} else {
@SuppressWarnings("unchecked")
Optional<T> r = (Optional<T>) supplier.get();
return Objects.requireNonNull(r);
}
}
传统默认可选值处理逻辑的问题
假设我们有三个可选值产生器,依次尝试获取用户信息,第一个获取不到就尝试第二个,第二个也获取不到就尝试第三个,传统实现方式如下:
import java.util.Optional;
public class TraditionalOptionalDemo {
// 模拟第一个产生器,返回空Optional
private static Optional<String> getFirstUser() {
return Optional.empty();
}
// 模拟第二个产生器,返回空Optional
private static Optional<String> getSecondUser() {
return Optional.empty();
}
// 模拟第三个产生器,返回有效值
private static Optional<String> getThirdUser() {
return Optional.of("默认用户");
}
public static void main(String[] args) {
Optional<String> result;
Optional<String> first = getFirstUser();
if (first.isPresent()) {
result = first;
} else {
Optional<String> second = getSecondUser();
if (second.isPresent()) {
result = second;
} else {
result = getThirdUser();
}
}
System.out.println(result.get());
}
}
这种实现方式嵌套了多层if-else判断,当产生器数量增多时,代码会变得越来越臃肿,可读性和维护性都会下降。
使用 or() 实现流式默认可选值产生器切换
利用or方法的链式调用特性,我们可以把上面的逻辑改写成更简洁的流式形式:
import java.util.Optional;
public class OptionalOrDemo {
// 模拟第一个产生器,返回空Optional
private static Optional<String> getFirstUser() {
return Optional.empty();
}
// 模拟第二个产生器,返回空Optional
private static Optional<String> getSecondUser() {
return Optional.empty();
}
// 模拟第三个产生器,返回有效值
private static Optional<String> getThirdUser() {
return Optional.of("默认用户");
}
public static void main(String[] args) {
Optional<String> result = getFirstUser()
.or(() -> getSecondUser())
.or(() -> getThirdUser());
System.out.println(result.get());
}
}
这段代码的逻辑非常清晰:首先尝试获取第一个可选值,如果为空就调用第一个or方法尝试第二个产生器,如果第二个还为空,就调用第二个or方法尝试第三个产生器,最终得到非空的可选值。整个过程是链式流式调用,没有嵌套的逻辑分支,代码简洁很多。
or() 方法的注意事项
- or方法传入的Supplier不能返回null,否则会抛出NullPointerException,如果产生器可能返回null,需要在Supplier内部做非空处理。
- or方法是惰性执行的,只有当前Optional为空时才会调用后续的Supplier,不会提前执行所有产生器的逻辑,不会造成不必要的性能损耗。
- or方法返回的是一个新的Optional对象,不会修改原有的Optional实例,符合Optional不可变的特性。
适用场景总结
or方法非常适合需要依次尝试多个可选值来源,直到获取到有效值的场景,比如多数据源查询、多配置项读取、降级逻辑处理等。相比传统的if-else嵌套或者flatMap链式处理,or方法的语义更明确,代码更简洁,是Java 9之后处理可选值默认逻辑的更优选择。