商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 如何在 Java 中利用 Optional.or() 在 Java 9 以后实现流式的默认可选值产生器切换逻辑

如何在 Java 中利用 Optional.or() 在 Java 9 以后实现流式的默认可选值产生器切换逻辑

  发布于2026-07-09 阅读(0)

扫一扫,手机访问

Ja va 9带来的这个 or() 方法,说实话,让很多以前不得不手动判断的繁琐操作一下子变得优雅多了。它的核心价值在于:当一个 Optional 里没值的时候,你可以提供一个备选的计算逻辑——而且是惰性的、可以链式衔接的那种。

如何在 Ja va 中利用 Optional.or() 在 Ja va 9 以后实现流式的默认可选值产生器切换逻辑

以前呢,要么用 isPresent() 走分支,要么用 orElseGet() 但最后拿到的就是一个普通值,Optional 的“包装”断了,后面想再 mapfilter 还得重新包一层。而 or() 的出现,直接把这块的体验拉高了一个档次。

理解 Optional.or() 的核心行为

or() 做的事情其实很简单:它接收一个 Supplier>,只有当当前 Optional 是空的时候,这个供给器才会被调用,然后返回它产生的新 Optional

说到关键点,几个地方值得留意:

  • 完全是惰性的。供给器函数不会提前触发,只有在你真正需要的那个时刻才被调用,这在涉及 I/O 或远程调用时特别重要。
  • 返回类型是 Optional,而不是一个普通的 T 值。这意味着你可以继续在这个结果上调用 map()filter(),甚至再接一个 or(),形成更长的链。
  • 这一点和 orElseGet() 的差别就出来了。orElseGet() 返回的是 T,Optional 上下文就此中断;而 or() 保持了 Optional 的“型”,非常适合多层 fallback 的场景。

构建可切换的默认值生成器链

利用这个特性,你可以把多个备选策略按照优先级串成一条链,每个环节都是一个独立的、可复用的 Supplier>

举个例子,查找用户配置时,我们可以依次尝试:系统属性 → 环境变量 → 配置文件 → 最后硬编码默认值。用 or() 写出来就是这样的:

Optional configValue = Optional.ofNullable(System.getProperty("app.timeout"))
    .or(() -> Optional.ofNullable(System.getenv("APP_TIMEOUT")))
    .or(() -> loadFromConfigFile("timeout"))
    .or(() -> Optional.of("30000")); // 最终兜底

这里 loadFromConfigFile() 是一个返回 Optional 的方法,里面可能做 I/O 或者解析。但注意,它只在前面所有策略都扑空的时候才会被触发,这就是惰性的价值。

封装可复用的 fallback 策略

如果同样的 fallback 逻辑在多个地方用到,建议把它们封装成静态方法,或者放到一个工具类里。代码会更干净,可读性也更好:

public class Fallbacks {
    public static Supplier> fromEnv(String key) {
        return () -> Optional.ofNullable(System.getenv(key));
    }

    public static Supplier> fromProps(String key) {
        return () -> Optional.ofNullable(System.getProperty(key));
    }

    public static Supplier> constant(String value) {
        return () -> Optional.of(value);
    }
}

这样用起来就清晰多了:

Optional timeout = Optional.ofNullable(config.getTimeout())
    .or(Fallbacks.fromProps("app.timeout"))
    .or(Fallbacks.fromEnv("APP_TIMEOUT"))
    .or(Fallbacks.constant("30000"));

注意嵌套 or() 与空值传播的边界

当然,or() 也不是银弹。它不会帮你吞掉异常,如果供给器内部抛了异常,整条链就会直接中断。所以,如果某个备选策略可能失败(比如网络请求),更稳妥的做法是在供给器内部自行捕获异常,然后返回一个空的 Optional

.or(() -> {
    try {
        return parseFromRemoteConfig("timeout");
    } catch (IOException e) {
        return Optional.empty();
    }
})

还有一点需要留意:or() 不会修改原始值。如果当前 Optional 非空,它直接原样返回,不会去调用供给器。这种“短路式备选”的行为模式,和逻辑运算中的 || 很像——第一个为真,后面的就不看了。

说到底,or() 是对 Optional 链式编程的一次有力补强,让多级 fallback 的写法从“分支嵌套”变成了“平铺直叙”,代码的意图也更清晰了。

本文转载于:https://www.php.cn/faq/2399800.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注