Java 8 Optional
类详解
Optional
是 Java 8 引入的容器类(位于 java.util
包),用于优雅地处理可能为 null
的值,避免显式的 null
检查和空指针异常(NullPointerException
)。
一、核心目的
- 显式处理空值:强制开发者考虑值缺失的场景。
- 减少空指针异常:通过链式调用替代嵌套的
if (obj != null)
检查。 - 表达意图:明确声明方法可能返回空值(替代
Javadoc
说明)。
二、创建 Optional
对象
方法 | 描述 | 示例 |
---|---|---|
Optional.empty() |
创建空容器 | Optional.empty() |
Optional.of(T value) |
创建非空容器(value 不可为 null ) |
Optional.of("Hello") |
Optional.ofNullable(T value) |
创建容器(允许 value 为 null ) |
Optional.ofNullable(null) |
Optional<String> emptyOpt = Optional.empty(); // 空容器
Optional<String> strOpt = Optional.of("Java"); // 非空值
Optional<String> nullableOpt = Optional.ofNullable(null); // 可为null
三、关键方法及使用场景
方法 | 描述 | 典型应用场景 |
---|---|---|
isPresent() |
检查值是否存在 | 替代 if (obj != null) |
ifPresent(Consumer<? super T> action) |
值存在时执行操作 | 简化空值检查后的操作 |
get() |
获取值(需先校验存在性) | 配合 isPresent() 使用(不推荐直接调用) |
orElse(T other) |
值存在时返回值,否则返回默认值 | 提供兜底值(如默认配置) |
orElseGet(Supplier<? extends T> supplier) |
值存在时返回值,否则执行 Supplier 生成值 |
延迟构造代价大的默认对象 |
orElseThrow(Supplier<? extends X> exceptionSupplier) |
值存在时返回值,否则抛出异常 | 强制要求值存在的场景(如数据验证) |
filter(Predicate<? super T> predicate) |
值存在且满足条件时返回原容器,否则返回空 | 条件过滤 |
map(Function<? super T, ? extends U> mapper) |
值存在时执行转换,返回新 Optional |
链式转换值(如从对象中提取字段) |
flatMap(Function<? super T, Optional<U>> mapper) |
展平嵌套的 Optional (避免 Optional<Optional<T>> ) |
连续操作返回 Optional 的方法 |
四、代码示例
- 基础使用
String name = "Alice";
Optional<String> nameOpt = Optional.ofNullable(name);
// 存在时输出
nameOpt.ifPresent(System.out::println); // 输出 "Alice"
// 不存在时提供默认值
String result = nameOpt.orElse("Unknown");
- 链式操作
public class User {
private Address address;
public Optional<Address> getAddress() {
return Optional.ofNullable(address);
}
}
public class Address {
private String city;
public Optional<String> getCity() {
return Optional.ofNullable(city);
}
}
// 获取用户的城巿(不存在时返回默认值)
String city = Optional.ofNullable(user)
.flatMap(User::getAddress) // 展平嵌套 Optional
.flatMap(Address::getCity)
.orElse("Unknown City");
- 条件过滤
Optional<User> userOpt = Optional.ofNullable(user);
// 仅当用户年龄大于18时返回
Optional<User> adult = userOpt.filter(u -> u.getAge() > 18);
- 异常处理
// 值不存在时抛出自定义异常
User user = userOpt.orElseThrow(() ->
new IllegalArgumentException("User not found!"));
五、最佳实践与注意事项
避免以下情况:
- 用
Optional
替代空集合:返回空集合(如Collections.emptyList()
)更合适。 - 作为方法参数:会导致代码冗余。
- 直接调用
get()
:须先调用isPresent()
检查。 - 字段声明:破坏序列化(
Optional
未实现Serializable
)。
- 用
推荐用法:
- 返回值:明确声明方法可能返回空值。
- 链式调用:结合
map()
、flatMap()
、filter()
安全处理嵌套对象。
六、设计哲学
Optional
的核心是鼓励函数式风格和防御性编程。通过显式处理空值,代码可读性和健壮性显著提升,是 Java 对空值问题的重要解决方案。
📌 关键点:
Optional
不是万能的,但合理使用能减少 70% 的空指针异常!