沉默是金,总会发光

大家好,我是沉默

写 Java,最怕的是什么?

答:空指针异常(NPE)
 

写 Java 这么多年,你是不是经常写这样的代码:

User user = getUserById(1);if (user != null) {    Address address = user.getAddress();    if (address != null) {        String city = address.getCity();        if (city != null) {            System.out.println(city.toUpperCase());        }    }}

一层层嵌套的 if 判空,像旋转楼梯,写着写着自己都崩溃。
 

这时,Java 8 给我们带来了一个救星 —— Optional

可现实是:Optional 出道十几年,却依然像个透明人,没人真正用。
 

这是它不好用,还是大家用错了?

-01-

为啥大家不用 Optional? 

1. 习惯就是枷锁

  • 老程序员:if 写十几年了,手感比 Optional 好。

  • 新人:书上压根没重点讲 Optional,感觉可有可无。

2. 用错了,劝退

反例:

Optional<User> opt = Optional.ofNullable(user);if (opt.isPresent()) {    User u = opt.get();    // 干活}

这不还是 if (user != null) 吗?换汤不换药

3. 团队没共识

你在 service 层返回 Optional<User>,隔壁老王一脸懵:

Optional<User> result = userService.findUser(id);// 然后呢?咋取值?咋判空?咋处理没找到?

结果一顿 .get() + .orElse(null),回到原始社会。

4. 框架兼容差

  • MyBatis:查不到,直接 null

  • SpringBoot:接口返回 Optional<String>,前端压根接不了。

于是大家结论:Optional 很鸡肋?

-02-

Optional 正确用法场景 

场景 1:链式取值

告别瀑布 if,一行搞定:

String city = Optional.ofNullable(user)        .map(User::getAddress)        .map(Address::getCity)        .orElse("未知城市");

清晰、简洁,还不用担心漏判空。

场景 2:方法返回值表达“可能不存在”

public Optional<User> findActiveUserByEmail(String email) {    User user = userRepo.findByEmail(email);    if (user != null && user.isActive()) {        return Optional.of(user);    }    return Optional.empty();}

调用方一看:哦,可能没有,要处理。不用猜“文档在哪,这会不会返回 null?”

场景 3:替代默认值逻辑

传统写法:

String name = user.getName();if (name == null) {    name = "匿名用户";}

Optional 写法:

String name = Optional.ofNullable(user.getName())                      .orElse("匿名用户");

更优雅。

图片

-03-

哪些地方千万别用 Optional?

参数类型

public void saveUser(Optional<User> user) { ... }

调用方会疯:传 null 还是传 Optional.empty()

实体类字段

public class User {    private Optional<String> email; // 灾难}

ORM、序列化全崩。

集合元素

List<Optional<String>> names; // 套娃地狱

接口返回给前端
Optional 是 Java 的概念,前端完全不懂。

图片

-04-

团队怎么推广 Optional?

  1. 统一规范

  • 查询方法:findById → Optional<User>

  • 取第一个:findFirstActive → Optional<Order>

  1. 写工具类降低门槛

public class Optionals {    public static <T> T orDefault(Optional<T> opt, T def) {        return opt.orElse(def);    }}

3. 代码审查温和引导
看到嵌套 if,就说:
“这块可以用 Optional 简化下,要不要试试?”

-05-

Optional 的进阶操作

filter:条件过滤

Optional.ofNullable(user)        .filter(u -> u.getAge() >= 18)        .ifPresent(u -> System.out.println("成年用户:" + u.getName()));

flatMap:避免嵌套 Optional

Optional<String> name = Optional.ofNullable(user)                .flatMap(u -> Optional.ofNullable(u.getNickName()));

orElseThrow:语义化抛异常

User user = userService.findById(123)                .orElseThrow(() -> new UserNotFoundException("用户不存在"));

-06-

总结

Optional 的局限性

  • 性能上有点开销。

  • 深层嵌套对象,写起来依然麻烦。

  • JSON / RPC 序列化不可用。

  • 没团队共识时,容易变成异类。

所以:它只是工具,不是银弹。

使用场景对比表

场景

推荐用法

链式取值

✅ 大力用,告别嵌套 if

方法返回值

✅ 表达“可能为空”

参数类型

❌ 禁用

实体类字段

❌ 禁用

集合元素

❌ 禁用

接口返回给前端

❌ 禁用

核心 takeaway

  • Optional 的核心价值:显式表达“可能不存在”。

  • 最佳场景:链式取值 + 方法返回值。

  • 不要滥用:参数、实体、集合、前端接口。

  • 推广秘诀:先规范,再引导。

学会用 Optional,不光是写代码优雅的问题,而是减少 NPE、提升代码可读性和团队协作效率的第一步。

热门文章

一套能保命的高并发实战指南

架构师必备:用 AI 快速生成架构图

-07-

粉丝福利

点点关注,送你互联网大厂面试题库,如果你正在找工作,又或者刚准备换工作。可以仔细阅读一下,或许对你有所帮助!

image.png

image.pngimage.png

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐