Optional<T>是一个容器类,用于表示一个值可能存在也可能不存在(但若存在,则一定非 null)。
如果值存在,isPresent()返回true,get()可获取该值;
同时还提供了一系列安全处理值存在与否的链式方法,如:
ifPresent():值存在时执行操作orElse()/orElseGet():值不存在时提供默认值map()/filter():对值进行转换或过滤
Optional是一个基于值的类(value-based class),不应使用==、hashCode()(用于身份识别)或同步操作,否则可能导致不可预测的行为 (理解java的值传递本质)。 它主要用于方法返回值,以更清晰、安全地表达“可能无结果”的语义,避免显式 null 检查。
1.字段:private static final Optional<?> EMPTY
private static final Optional<?> EMPTY = new Optional<>();
- 作用:一个共享的、空的
Optional实例。 - 类型:
Optional<?>表示“未知类型的空 Optional”。 - 用途:作为所有
empty()调用的底层单例(节省内存)。 - 注意:它是
private的,外部不能直接访问。
2.字段:private final T value
private final T value;
作用:存储实际的值。
语义:
- 若
value != null→ 有值(present) - 若
value == null→ 无值(empty)
- 若
不可变性:
final保证Optional是不可变对象(符合 value-based 类设计)。
3.私有构造函数:private Optional()
private Optional() { this.value = null; }
- 作用:创建一个空的
Optional(仅用于初始化EMPTY)。 - 不可外部调用:因为是
private。
4.静态方法:public static <T> Optional<T> empty()
public static <T> Optional<T> empty()``` { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; }
- 作用:返回一个类型安全的空 Optional。
- 实现:强制将
EMPTY转为Optional<T>(利用泛型擦除,运行时安全)。 - 使用建议:永远不要用
== Optional.empty()判断是否为空,应使用isPresent()。
5.私有构造函数:private Optional(T value)
private Optional(T value) { this.value = Objects.requireNonNull(value); }
- 作用:创建一个包含非 null 值的
Optional。 - 校验:若传入
null,抛出NullPointerException。 - 仅内部使用:由
of()调用。
6.静态方法:public static <T> Optional<T> of(T value)
public static <T> Optional<T> of(T value)
- 作用:创建一个包含非 null 值的
Optional。 - 异常:若
value == null,抛出NullPointerException。 - 适用场景:确定值不为 null时使用。
7.静态方法:public static <T> Optional<T> ofNullable(T value)
public static <T> Optional<T> ofNullable(T value) { return value == null ? empty() : of(value); }
作用:安全地包装可能为 null 的值。
逻辑:
- 若
value != null→return of(value) - 若
value == null→return empty()
- 若
最常用的创建方式,用于处理不确定是否为 null 的值。
8.实例方法:public T get()
public T get() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; }
- 作用:获取值。
- 风险:若无值(
value == null),抛出NoSuchElementException。 - 建议:避免直接使用,除非你 100% 确定有值。优先使用
orElse()、ifPresent()等。
Optional<U> uOptional = list.stream() .filter(item -> UEnum.XX.getCode().equals(item.getName())) .findFirst(); if (!uOptional.isPresent()) { return null; } U res = uOptional.get(); return res.getName();
9.实例方法:public boolean isPresent()
public boolean isPresent() { return value != null; }
- 作用:判断是否有值。
- 返回:
true→value != nullfalse→value == null
- 用途:可用于条件判断,但更推荐函数式风格(如
ifPresent)。
10.实例方法:public void ifPresent(Consumer<? super T> consumer)
public void ifPresent(Consumer<? super T> consumer) { if (value != null) consumer.accept(value); }
- 作用:如果有值,执行
consumer.accept(value);否则什么都不做。 - 优点:避免显式 if 判断,代码更简洁。
- 示例:
Map<String, List<Long>> map = Maps.newHashMap(); Optional.ofNullable(types).ifPresent(list -> map.put(DictAlias.TYPE.getCode(), list)); #使用的是 `Optional` 类的7,10两个方法
11.实例方法:public Optional<T> filter(Predicate<? super T> predicate)
public Optional<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); if (!isPresent()) return this; else return predicate.test(value) ? this : empty(); }
作用:对值进行条件过滤。
逻辑:
- 无值 → 返回
this(即empty()) - 有值且
predicate.test(value) == true→ 返回this - 有值但不满足条件 → 返回
empty()
- 无值 → 返回
用途:链式过滤。
示例:
Optional<String> s = Optional.of("hello"); s.filter(x -> x.length() > 10); // empty
12.实例方法:public <U> Optional<U> map(Function<? super T, ? extends U> mapper)
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Optional.ofNullable(mapper.apply(value)); } }
- 作用:对值进行转换,并自动处理 null。
- 逻辑:
- 无值 → 返回
empty() - 有值 → 调用
mapper.apply(value),然后用ofNullable()包装结果
- 无值 → 返回
- 关键点:如果
mapper返回null,结果是empty(),不会抛 NPE。 - 用途:链式转换(如从
Optional<User>到Optional<String>)。 map的核心价值- 空安全:Optional 为空时跳过转换。
- null 安全:转换结果为 null 时自动变为空 Optional。
- 链式编程:支持流畅的
.map().filter().map()风格。 - 避免样板代码:无需手动写
if (x != null)。
- 示例:
# 1.Optional 有值,且 `mapper` 返回非 null Optional<User> userOpt = Optional.of(new User("alice")); Optional<String> upperName = userOpt.map(User::getName) //Optional["alice"] .map(String::toUpperCase); // Optional["ALICE"] System.out.println(upperName); // Optional[ALICE] # 2.Optional 有值,但 `mapper` 返回 `null` Optional<String> opt = Optional.of("hello"); // 假设有一个函数可能返回 null Optional<String> result = opt.map(s -> s.equals("world") ? "OK" : null); System.out.println(result); // Optional.empty # 3.Optional 本身为空 `mapper` 根本不会被执行 Optional<User> emptyUser = Optional.empty(); Optional<String> name = emptyUser.map(User::getName); // 不会调用 getName() System.out.println(name); // Optional.empty
// 传统方式(需要多层 null 检查) User user = getUser(); // 可能返回 null String upperName = null; if (user != null) { String name = user.getName(); // getName() 可能返回 null! if (name != null) { upperName = name.toUpperCase(); } } // 最终 upperName 还可能是 null VS 用 `Optional.map()` Optional<String> upperName = Optional.ofNullable(getUser()) .map(User::getName) .map(String::toUpperCase); // 自动处理所有 null 情况
13.实例方法:public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Objects.requireNonNull(mapper.apply(value)); } }
作用:对值应用一个返回
Optional的函数,并“拍平”嵌套。与
map的区别:map:Optional<T> → Optional<Optional<U>>(需要拍平)flatMap:Optional<T> → Optional<U>(自动拍平)
用途:处理返回
Optional的方法链。示例:
userOpt.flatMap(User::getAddress); // getAddress() 返回 Optional<Address>mapvsflatMap快速区分
| 方法 | 适用场景 | 返回类型处理 |
|---|---|---|
map | 转换函数返回普通对象(如String,Integer) | 自动包装为Optional<U> |
flatMap | 转换函数返回Optional<U> | 不二次包装,直接返回该Optional |
// map 会导致嵌套 Optional<Optional<String>> bad = userOpt.map(u -> Optional.of(u.getName())); // flatMap 避免嵌套 Optional<String> good = userOpt.flatMap(u -> Optional.of(u.getName()));
14.实例方法:public T orElse(T other)
public T orElse(T other) { return value != null ? value : other; }
作用:有值返回值,否则返回
other。注意:
other是立即求值的(即使不用也会计算)。示例:
# orElse方法 String name = opt.orElse("Guest"); # 7,14组合方法 Optional.ofNullable(users).orElse(Collections.emptyList())
15.实例方法:public T orElseGet(Supplier<? extends T> other)
public T orElseGet(Supplier<? extends T> other) { return value != null ? value : other.get(); }
- 作用:有值返回值,否则调用
other.get()获取默认值。 - 优势:
Supplier是惰性求值,仅在需要时调用(适合开销大的操作)。 - 示例:
config.orElseGet(() -> loadFromDisk());
16.实例方法:public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { if (value != null) { return value; } else { throw exceptionSupplier.get(); } }
作用:有值返回值,否则抛出异常。
用途:替代
get(),提供清晰的错误语义。示例:
user.orElseThrow(UserNotFoundException::new);
17.重写方法:public boolean equals(Object obj)
@Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof Optional)) { return false; } Optional<?> other = (Optional<?>) obj; return Objects.equals(value, other.value); }
规则:
- 都是
Optional - 要么都为空,要么值通过
equals()相等
- 都是
用途:支持集合操作(如
Set<Optional>),但不推荐这样做。
18.重写方法:public int hashCode()
@Override public int hashCode() { return Objects.hashCode(value); }
规则:
- 有值 →
value.hashCode() - 无值 →
0
- 有值 →
与
equals一致,满足哈希契约。
19.重写方法:public String toString()
@Override public String toString() { return value != null ? String.format("Optional[%s]", value) : "Optional.empty"; }
格式:
- 有值:
"Optional[value]" - 无值:
"Optional.empty"
- 有值:
用途:调试友好,明确区分空与非空。
✅ 总结:Optional 的设计哲学
表格
| 类别 | 方法 | 核心目的 |
|---|---|---|
| 创建 | empty(),of(),ofNullable() | 安全构造 Optional |
| 检查 | isPresent(),get() | 判断/获取值(谨慎用get) |
| 消费 | ifPresent() | 有值则执行副作用 |
| 转换 | map(),flatMap() | 链式处理值 |
| 过滤 | filter() | 条件保留值 |
| 回退 | orElse(),orElseGet(),orElseThrow() | 处理无值情况 |
| 对象契约 | equals(),hashCode(),toString() | 支持调试和集合(但不鼓励用于集合) |