当前位置: 首页 > news >正文

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 APICollectors 的增强。

一个常见的例子是 flatMappingOptional.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 8Optional 初版:of, empty, get, orElse, ifPresent…
Java 9ifPresentOrElse()or()stream()
Java 10–20无直接增强,但受益于 Stream API 的升级
Java 21可结合 模式匹配 for switch 优雅解包

空指针规避工具函数式 API 拼图,再到 模式匹配语法配合
Optional 的进化,让 Java 的可读性与表达力逐步向 Scala、Kotlin 等语言靠近。

http://www.dtcms.com/a/353510.html

相关文章:

  • 每日算法题【链表】:链表分割、链表的回文结构
  • 关于vscode的右键常用操作以及自定义快捷键
  • 密码管理中注释与重定向密码安全隐患及修复方案
  • 高并发内存池(12)-ThreadCache回收内存
  • Virtual PLCnext Controller 本地网络部署平台
  • Pandas DataFrame 列数操作完全指南
  • 高通平台蓝牙学习-- 基于WCN685x 的蓝牙低功耗(LE)功能
  • 浏览器与计算机网络
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘click’问题
  • k8s部署pgsql集群
  • 【Spring Cloud 微服务】5.架构的智慧枢纽:深度剖析 Nacos 注册中心
  • K8s持久化存储:PV与PVC
  • K8s 二次开发漫游录
  • 前端-npm和yarn的区别
  • 时序数据库的 LSM 树介绍
  • 计算机网络——DNS,ARP,RARP,DHCP,ICMP
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘websockets’问题
  • 时序数据库全景指南:从场景选型到内核拆解
  • Linux(十九)——CPU、I/O、网络与内核参数调优指南
  • 字库原理 GB2312-80
  • rk3588开发板最新kernel6.1下载(RK3588SDK源码下载)和环境搭建
  • 基于结构化码本的分层DNN框架用于高效语音增强
  • 第18章|变量:把数据装进“盒子”的正确方式
  • 【STM32】将 FreeRTOS移植到STM32F103RCT6 详细流程
  • 【开发配置】GitLab CR(Code Review)规则配置清单
  • 论文翻译:BRILLM: BRAIN-INSPIRED LARGE LANGUAGE MODEL
  • 在Excel和WPS表格中通过查找替换对单元格批量强制换行
  • 【C++】map 容器的使用
  • 论文阅读:Gorilla: Large Language Model Connected with Massive APIs
  • Python基础:PyMySQL