Java Optional 完全指南,如何优雅处理 null?
摘要:写在开头:很久没有发博了,除去工作忙等因素,有时候觉得记录这些AI一分钟就能给出结果的代码,没有多少意义。不过最近在看面试题,看到了Optional,发现自己工作两年多来,从来没有在项目里用到过这个类,被大家称之为处理null的利器,于是心
写在开头:很久没有发博了,除去工作忙等因素,有时候觉得记录这些AI一分钟就能给出结果的代码,没有多少意义。不过最近在看面试题,看到了Optional,发现自己工作两年多来,从来没有在项目里用到过这个类,被大家称之为处理null的利器,于是心血来潮就把这个知识点简单记录下吧
——从繁琐的 null 检查到流畅的链式调用——
一、日常处理null的方法
日常开发中,常常遇到NullPointException,我的做法往往是,要么手动try...Catch...,要么用if嵌套判断:
if (user != null) {
Address address = user.getAddress();
if (address != null) {
City city = address.getCity();
if (city != null) {
return city.getName();
}
}
}
return "未知城市";
这种代码不仅冗长,而且难以维护。Java 8 引入的 Optional 正是为了解决这一痛点。
二、Optional 是什么?
Optional 是一个容器对象,它可能包含非 null 值,也可能为空。它的设计目标是:
提供一种更优雅的方式来处理可能为 null 的值
强制开发者显式处理 null 情况,减少 NPE 风险
支持函数式编程风格,代码更简洁
核心原则:Optional 不是为了避免所有 null,而是让 null 的处理显性化、可控化。
三、创建 Optional 的三种方式
// 1. of() - 创建非空 Optional,传入 null 会立即抛出 NPE
Optional<String> opt1 = Optional.of("Hello");
// Optional.of(null); // 会抛出 NullPointerException
// 2. ofNullable() - 创建可能为空的 Optional(最常用)
Optional<String> opt2 = Optional.ofNullable(getValue()); // 可能为 null
Optional<String> opt3 = Optional.ofNullable(null); // 允许的
// 3. empty() - 创建空 Optional
Optional<String> opt4 = Optional.empty();
最佳实践:方法返回值可能为 null 时,使用 Optional.ofNullable() 包装,将 null 风险提前暴露。
四、常用操作:存在性检查与值获取
4.1 判断值是否存在
Optional<String> opt = Optional.ofNullable("测试值");
// 不推荐:虽然能用,但失去了 Optional 的优势
if (opt.isPresent()) {
System.out.println(opt.get());
}
// 推荐:存在则消费,不存在则什么都不做
opt.ifPresent(value -> System.out.println("值存在: " + value));
4.2 获取值(提供默认值)
String name = null;
// orElse() - 为空时返回默认值
String result1 = Optional.ofNullable(name).orElse("默认值");
// 输出: 默认值
// orElseGet() - 为空时通过 Supplier 生成值(延迟计算,推荐)
String result2 = Optional.ofNullable(name)
.orElseGet(() -> generateDefaultName());
// 输出: 动态生成的默认值
// orElseThrow() - 为空时抛出异常
String result3 = Optional.ofNullable(name)
.orElseThrow(() -> new RuntimeException("值不能为空"));
orElse vs orElseGet:如果默认值需要复杂计算,用 orElseGet() 避免不必要的计算开销。
