optional的核心是让空值处理不可绕过、语义清晰、链路安全;复习抓三条主线:创建逻辑(分清of/ofnullable/empty场景)、消费方式(禁用get(),优先链式操作)、使用边界(禁作字段/参数/集合包装)。

Optional 的核心不是“怎么避免空指针”,而是“怎么让空值处理变得不可绕过、语义清晰、链路安全”。复习时抓住三条主线:创建逻辑、消费方式、使用边界。
一、创建必须分清场景,不能混用
三种创建方式对应三类数据来源:
- of(value):只用于你100%确定非空的值,比如硬编码字符串、已校验过的参数。传 null 直接抛 NPE,是设计上的“断言”而非容错。
- ofNullable(value):唯一该在业务中高频使用的创建方法。任何可能来自数据库、HTTP、用户输入、配置项的值,都该走它——把判空责任交给 Optional,而不是自己写 if (x != null)。
- empty():用于显式构造“无结果”状态,比如条件不满足时提前返回、兜底逻辑分支。不是为了初始化字段或占位。
二、取值和转换必须拒绝 get(),优先链式操作
直接调用 get() 和手动 isPresent() + get() 组合,等于把 Optional 当成“带壳的 null”,完全违背设计初衷。
- 用 orElse(default) 或 orElseGet(Supplier) 替代“先判空再赋默认值”。后者适合默认值生成开销大(如查库、计算)的场景。
- 嵌套对象访问(如 user.getAddress().getCity())直接转为 map(Address::getCity);若 getAddress() 本身也返回 Optional,则用 flatMap(User::getAddress) 避免 Optional
>。 - 加业务规则?用 filter(u -> u.getAge() >= 18),比 if (u != null && u.getAge() >= 18) 更聚焦意图。
三、严格守住使用边界,避开典型误用
Optional 是“返回值契约”,不是通用包装器:
- 禁止作为类字段:它没实现 Serializable,且引入双重空(引用本身可 null + 内部可 empty),破坏封装性。
- 禁止作为方法参数:调用方传 Optional 就意味着他本可以自己处理空,却把责任推给被调用方,语义倒置。
-
集合不适用 Optional:空集合(List.of())本身已是“存在但为空”的合法状态,用 Optional
- > 属于过度包装。
本质上,Optional 是一套 API 约束力:它不消灭 null,而是把“值可能不存在”这个事实从隐式(靠文档/经验猜测)变成显式(编译期提醒+运行期强制)。复习时多想一句:“我这么写,调用者还能忽略空吗?” —— 答案是否定的,就对了。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











