Optional 重构判空的核心是显式表达“可能为空”语义并用链式调用替代嵌套 if;应从返回值开始改用 Optional 类型,避免包装已有方法,且仅用于返回值而非字段、参数或集合元素。

用 Optional 重构判空代码,核心不是“套上 Optional”,而是把“可能为空”的语义显式表达出来,并用链式调用替代嵌套 if。它不能消除所有空指针,但能大幅减少防御性判空、提升可读性和 API 意图清晰度。
从返回值开始:方法主动声明“可能无值”
不要在已有方法里硬塞 Optional,而是让原本可能返回 null 的方法,改用 Optional 作为返回类型。这样调用方一眼就知道要处理“无值”情况。
- ✅ 好做法:把
User findUserById(Long id)改成Optional<user> findUserById(Long id)</user> - ❌ 避免:
Optional.ofNullable(findUserById(id))包一层——这没解决根本问题,还掩盖了设计意图 - 注意:
Optional不适合用作字段、参数或集合元素;它专为“方法返回值”而生
用 map 和 flatMap 替代多层判空
当需要连续访问对象属性(比如 user.getAddress().getCity().getName()),传统写法要嵌套 3 层 if。用 Optional 链式调用,逻辑扁平且安全:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.map(City::getName)
.orElse("未知城市");
-
map:适用于返回普通对象的 getter(如getAddress()) -
flatMap:适用于本身返回Optional的方法(如findCityById()),避免Optional<optional>></optional> - 每一步都自动短路:任意一环为空,后续不执行,最终落到
orElse或orElseThrow
用 orElse 系列明确“兜底策略”,别再写 == null ? x : y
把空值处理逻辑集中、具名化,而不是散落在各处的三元运算符:
立即学习“Java免费学习笔记(深入)”;
-
orElse("默认名"):直接给默认值 -
orElseGet(() -> computeDefaultName()):延迟计算,默认值开销大时用(避免无谓构造) -
orElseThrow(() -> new UserNotFoundException("ID 不存在")):明确表达“空=异常”,比if (u == null) throw...更紧凑 - 慎用
get():它不带检查,和直接解引用null一样危险,仅在你 100% 确认非空时用(通常不该出现)
组合多个 Optional:用 filter 和 ifPresent 替代条件分支
当需要“有值且满足某条件才执行操作”,用 filter + ifPresent 比 if (u != null && u.isActive()) { ... } 更函数式:
Optional.ofNullable(user)
.filter(u -> u.isActive())
.filter(u -> u.getAge() > 18)
.ifPresent(u -> sendWelcomeEmail(u));
-
filter不匹配就变空,自然跳过后续 -
ifPresent是消费动作,适合发邮件、记日志等副作用操作 - 想转换后继续链式?用
map;想终止并返回结果?用orElse系列

















