Optional 是轻量级空值契约容器,非通用包装器;其核心是不可变 final T value 字段建模“空/非空”语义,of() 主动拒绝 null 以明确契约,ofNullable() 才处理不确定性,EMPTY 单例复用体现设计精简。

分析 Java 中 Optional 的源码,关键不是逐行读完所有代码,而是抓住它的设计契约、不可变性、空值语义建模这三条主线。它本质上是一个“轻量级契约容器”,不是通用包装器,源码结构非常精简(JDK 8–21 始终维持在 300 行以内),但每一处都服务于一个明确目的。
看构造逻辑:区分“必须非空”和“允许为空”的语义边界
源码中两个核心静态工厂方法定义了使用前提:
-
Optional.of(T value)内部调用私有构造器new Optional(value),而该构造器第一行就是Objects.requireNonNull(value)—— 这意味着 of() 不是“防 NPE”,而是主动拒绝模糊语义。传 null 就炸,不给你侥幸机会。 -
Optional.ofNullable(T value)才是真正处理不确定性的入口:它直接调用私有无参构造器new Optional()(value = null),或带参构造器(value = 传入值)。这里 value 字段是否为 null,就决定了isPresent()的返回值 —— 空与非空,完全由 value 字段的 runtime 状态决定,没有额外标记字段。
看字段与不可变性:value 是唯一状态,且 final
类中仅有一个关键字段:
-
private final T value;—— final 保证不可变,也符合“值类型(value-based)”定位; -
private static final Optional> EMPTY = new Optional();—— 全局共享空实例,避免重复创建;
注意:EMPTY 是 Optional> 类型,通过泛型擦除 + 强制转型实现类型安全复用(empty() 方法里 (Optional<t>) EMPTY</t>)。这不是 hack,而是 JDK 明确接受的优化手段。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
看链式方法:map 和 flatMap 的底层差异决定安全性
二者都返回新 Optional,但行为本质不同:
-
map(Function super T, ? extends U> mapper):先判isPresent(),是则执行映射并用Optional.ofNullable(result)包装 —— 自动处理映射函数可能返回 null 的情况; -
flatMap(Function super T, Optional<u>> mapper)</u>:同样先判存在,但要求 mapper 必须返回Optional,然后直接返回该结果 —— 避免嵌套 Optional<Optional<T>>,是安全穿透多层对象的关键(如user.flatMap(User::getAddress).map(Address::getCity))。
看 orElse 系列:理解“立即求值”与“延迟求值”的性能分水岭
这是线上最容易被忽略的性能陷阱:
-
orElse(T other):不管当前 Optional 是否有值,other表达式一定被执行(比如orElse(new HeavyObject()),每次调用都 new); -
orElseGet(Supplier extends T> supplier):仅当value == null时才调用supplier.get()—— 默认值构造开销大时必须用它(如查数据库、远程调用、复杂计算);
翻看源码实现,两者逻辑就一行区别:return value != null ? value : supplier.get(); —— 简单,但影响真实吞吐。

















