Optional 是 Java 8 用于显式表达“可能为空”的 API 设计工具,应仅作返回值、避免作参数或字段,优先链式操作、安全取值并正确选择工厂方法。

Java 8 的 Optional 不是用来消灭 null 的,而是帮你把“可能为空”这件事显式写进 API 里,倒逼调用方必须面对和处理空值场景。用得好,代码更安全、更易读;用得随意,反而增加复杂度甚至掩盖问题。
只作返回值,不作参数或字段
Optional 的设计初衷是作为方法的返回类型,向调用方清晰传达“这个结果可能不存在”。它不是通用包装器,不该出现在其他位置。
- ✅ 正确:
public Optional<User> findUserById(Long id)—— 调用方一眼看出需处理空情况 - ❌ 错误:
public void processUser(Optional<User> user)—— 调用方还得先.orElse(null),失去语义价值 - ❌ 错误:
private Optional<String> name;—— 序列化、反射、日志打印、调试全变麻烦,且违背封装本意
优先链式操作,少用 isPresent + get
写 if (opt.isPresent()) { opt.get().doSomething(); } 和传统 if (obj != null) 没本质区别,还多一层包装。应转向函数式风格的链式调用。
- 用
map转换值:opt.map(User::getName).orElse("匿名") - 用
flatMap处理嵌套可空对象:userOpt.flatMap(User::getAddress).flatMap(Address::getCity) - 用
filter做条件筛选:opt.filter(u -> u.isActive()).orElse(null)
安全取值,避开 get() 的陷阱
get() 在空时抛 NoSuchElementException,和直接调用 null 方法一样危险。应始终选择有兜底逻辑的方法。
立即学习“Java免费学习笔记(深入)”;
-
orElse(T):适合简单默认值,如orElse("N/A") -
orElseGet(Supplier):默认值计算开销大时使用,避免无谓执行,如orElseGet(this::fetchDefault) -
orElseThrow(Supplier):业务上不允许为空时,抛定制异常,如orElseThrow(() -> new UserNotFoundException(id))
创建时选对工厂方法
不同创建方式语义不同,混用容易引入 NPE 或逻辑偏差。
-
Optional.of(value):仅用于你 100% 确定value非空,否则立刻抛NullPointerException -
Optional.ofNullable(value):最常用,null→Optional.empty(),安全兜底 -
Optional.empty():明确构造空实例,语义清晰,比ofNullable(null)更直白


















