Optional 的核心是显式封装“值是否存在”语义,聚焦业务逻辑而非空值防御;支持 ifPresent、ifPresentOrElse、map/flatMap 链式取值及 orElse/orElseGet 等方式安全处理空值。

用 Optional 替代 if-else 判空,核心不是为了“炫技”,而是把“值是否存在”这个语义显式封装起来,让代码聚焦在“做什么”,而不是“防什么”。它不消除 null,但能隔离 null 的传播路径,避免层层嵌套和重复检查。
基础判空:替代单层 if (obj != null)
当只需判断一个对象是否为空并做简单处理时,Optional 提供了更紧凑的表达:
-
仅执行非空逻辑:用
ifPresent()替代if (obj != null) { ... }Optional.ofNullable(user).ifPresent(u -> System.out.println(u.getName())); -
区分存在/缺失场景:Java 9+ 支持
ifPresentOrElse(),直接对应 if-else 分支
Optional.ofNullable(user)<br> .ifPresentOrElse(<br> u -> sendWelcomeEmail(u),<br> () -> log.warn("用户未登录,跳过欢迎邮件")<br> );
链式取值:替代多层嵌套 if
访问 user.getAddress().getCity() 这类深层属性时,传统写法需逐层判空;Optional 的 map() 会自动短路——任一环节为 null,后续 map 不执行,最终返回空 Optional:
- 安全获取嵌套字段:
String city = Optional.ofNullable(user)<br> .map(User::getAddress)<br> .map(Address::getCity)<br> .orElse("未知城市"); - 避免 Optional 套娃:
若getAddress()返回的是Optional<address></address>,就该用flatMap()而非map(),否则会得到Optional<optional>></optional>。
默认值与异常:替代三元表达式和手动 throw
对空值提供兜底行为时,Optional 提供了语义更清晰的选择:
-
orElse(T other):立即计算默认值(适合轻量、无副作用)String name = Optional.ofNullable(user).map(User::getName).orElse("游客"); -
orElseGet(Supplier extends T> supplier):延迟执行,默认值生成开销大或含 I/O 时更合适.orElseGet(() -> fetchDefaultNameFromDB()) -
orElseThrow(Supplier extends X> exceptionSupplier):空时抛自定义异常,比if (x == null) throw new Xxx()更函数化
Order order = Optional.ofNullable(orderId)<br> .map(orderService::findById)<br> .orElseThrow(() -> new OrderNotFoundException("订单不存在"));
注意事项:别滥用,也别误用
Optional 是为返回值设计的容器,不是用来包装方法参数或字段的:
- ❌ 不要把
Optional<user></user>当作字段类型(破坏封装性,且序列化/ORM 支持差) - ❌ 不要用
Optional.get()直接取值(它不判空,失败就抛NoSuchElementException,等于换种方式写 if) - ✅ 正确姿势是:从可能为 null 的源头(如 DAO 查询、外部 API 调用)开始用
ofNullable()封装,之后全程用 map/filter/orElse 等声明式操作

















