optional本质是显式声明“可能为空”的契约容器,非集合也非语法糖;创建需分of(确定非空)、ofnullable(不确定)、empty(明确无值);消费应避免get(),按意图选ifpresent、orelsethrow等;链式操作map/filter/flatmap实现空值自动传播。

本质:一个显式声明“可能为空”的契约容器
Optional 不是集合,不实现 Collection 接口;它不存储多个值,也不支持迭代。它的唯一职责是把“这个值可能不存在”从隐式约定(靠文档、靠经验、靠运气)变成类型系统可感知的显式信号。返回 Optional<user></user> 的方法,就是在说:“我找不到时不会返回 null,也不会抛异常——我会返回一个空容器,请你主动处理缺失场景。”
创建:三类入口,语义分明
- Optional.of(value):仅用于你100%确定 value 非 null 的场景(如常量、已校验参数)。传 null 直接炸——这是设计好的“安全阀”,逼你确认前提。
- Optional.ofNullable(value):最常用。数据库查询结果、HTTP 响应体、配置项读取……所有外部/不确定来源都走这里。null → empty,非 null → 包装,一步到位。
-
Optional.empty():明确表达“此处无值”,比
ofNullable(null)更直白,适合初始化、兜底返回或条件分支中的空路径。
消费:拒绝裸 get(),拥抱意图驱动操作
直接调用 get() 等同于绕过 Optional 的全部价值。正确姿势是按业务意图选方法:
- “有就干点啥,没有就算了” →
ifPresent(action)(Java 8)或ifPresentOrElse(action, emptyAction)(Java 9+) - “必须有值,没有就报错” →
orElseThrow(() -> new XxxException("缺用户"))(Java 10+),比get()+ 手动 try-catch 更精准 - “没值时给个默认,但默认值构造成本高” →
orElseGet(() -> heavyInit())(延迟执行),而非orElse(heavyInit())(立即执行) - “要的是值,不是 Optional” → 优先用
orElse(...)或orElseGet(...),而不是isPresent() ? get() : ...—— 后者冗余且易出竞态(中间被改)
链式转换:map/filter/flatMap 是函数式骨架
真正体现 Optional 设计深度的地方。它们让“空值传播”自动发生,无需手动判空:
-
map(u -> u.getAddress().getCity()):若 user 为空,整条链自然返回 empty;若 address 或 city 为 null?那就不是 Optional 职责了——说明 domain 模型本身没用 Optional 封装,该修的是数据结构,不是硬加判空 -
filter(u -> u.isActive()):值存在且满足条件才保留,否则变 empty。替代if (u != null && u.isActive()) -
flatMap(u -> Optional.ofNullable(u.getProfile())):当你映射后得到的仍是 Optional(比如查关联对象),用 flatMap 避免嵌套 Optional>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











