Optional 从 Java 8 到 21 的演进之路
在 Java 世界里,Optional 的出现被视为对 空指针异常(NPE) 的一次“官方回应”。
从 JDK 8 引入,到 JDK 21 与模式匹配结合,Optional 的功能逐步增强,越来越贴近函数式风格。本文将带你按时间线梳理它的演进之路。
一、Java 8:Optional 初登场
在 JDK 8(2014)中,Optional<T> 被引入,用来表示一个可能存在或不存在的值。
它最初的目标是:避免返回 null,提升 API 可读性。
核心方法:
Optional<String> opt = Optional.of("Hello");
Optional<String> empty = Optional.empty();
System.out.println(opt.isPresent()); // true
System.out.println(empty.isPresent()); // false
// 取值
System.out.println(opt.get()); // Hello
// 安全取值
System.out.println(opt.orElse("default")); // Hello
System.out.println(empty.orElse("default")); // default
缺点也很明显:
if (opt.isPresent()) ...写法依然啰嗦;- 没有流式 API 结合;
- 没有提供“有值/无值双分支”的优雅处理。
二、Java 9:实用方法增强
JDK 9(2017)给 Optional 加入了 三个关键增强,极大提升了实用性。
1. ifPresentOrElse()
直接表达 有值时执行 A,没值时执行 B。
Optional<String> opt = Optional.of("Java9");
opt.ifPresentOrElse(
v -> System.out.println("Value: " + v),
() -> System.out.println("No value")
);
// 输出:Value: Java9
2. or()
在空值时返回另一个 Optional,方便级联。
Optional<String> opt = Optional.empty();
String result = opt
.or(() -> Optional.of("fallback"))
.get();
System.out.println(result); // fallback
3. stream()
把 Optional 转换为 0 或 1 个元素的 Stream,与流式操作无缝衔接。
List<String> list = Optional.of("A")
.stream()
.map(String::toLowerCase)
.toList();
System.out.println(list); // [a]
👉 这一增强使得 Optional 与 Stream API 结合更自然,成为函数式写法的“好搭档”。
三、Java 10 ~ 20:平稳期
在 JDK 10 到 JDK 20 期间,Optional 本身没有新增方法,但它受益于 Stream API 与 Collectors 的增强。
一个常见的例子是 flatMapping 与 Optional.stream() 结合:
Stream<Optional<String>> stream = Stream.of(Optional.of("x"), Optional.empty());
List<String> result = stream
.flatMap(Optional::stream) // 自动展开非空值
.toList();
System.out.println(result); // [x]
👉 虽然 Optional 本身没变,但它在函数式编程场景中的地位越来越稳固。
四、Java 21:模式匹配加持
JDK 21(2023 LTS)虽然没有为 Optional 新增方法,但它和 模式匹配 for switch 结合后,逻辑更优雅。
如果要用 switch + Optional,你可以这样写:
Optional<String> opt = Optional.of("Java21");
switch (opt) {
case Optional<String> o when o.isPresent() ->
System.out.println("Value: " + o.get());
case Optional<String> o ->
System.out.println("Empty");
}
这里用的是 守卫(when 子句),它在 JDK 21 里已经是预览特性(需要加 --enable-preview 编译/运行)。
五、总结:Optional 的演进路线
| 版本 | 特性增强 |
|---|---|
| Java 8 | Optional 初版:of, empty, get, orElse, ifPresent… |
| Java 9 | ifPresentOrElse()、or()、stream() |
| Java 10–20 | 无直接增强,但受益于 Stream API 的升级 |
| Java 21 | 可结合 模式匹配 for switch 优雅解包 |
从 空指针规避工具 到 函数式 API 拼图,再到 模式匹配语法配合,Optional 的进化,让 Java 的可读性与表达力逐步向 Scala、Kotlin 等语言靠近。
更多推荐


所有评论(0)