Optional 类主要解决的问题是臭名昭著的空指针异常NPE(NullPointerException)
在 Java 8 之前,任何访问对象方法或属性的调用都可能导致 NullPointerException

  1. String isocode = user.getAddress().getCountry().getIsocode().toUpperCase();

在这个小示例中,如果我们需要确保不触发异常,就得在访问每一个值之前对其进行明确地检查:

  1. if (user != null) {
  2. Address address = user.getAddress();
  3. if (address != null) {
  4. Country country = address.getCountry();
  5. if (country != null) {
  6. String isocode = country.getIsocode();
  7. if (isocode != null) {
  8. isocode = isocode.toUpperCase();
  9. }
  10. }
  11. }
  12. }

使用Optional可以精简代码,降低复杂度:

  1. String result = Optional.ofNullable(user)
  2. .flatMap(User::getAddress)
  3. .flatMap(Address::getCountry)
  4. .map(Country::getIsocode)
  5. .orElse("default");

Optional 创建

创建 Optional 对象主要三种:

  • Optional.of(T t):创建一个 Optional 对象,参数 t 必须非空;
  • Optional.empty():创建一个空的Optional实例;
  • Optional.ofNullable(T t):创建一个Optional对象,参数t 可以为 null。
  1. empty(): 尝试访问 emptyOpt 变量的值会导致 NoSuchElementException。

    1. Optional<User> emptyOpt = Optional.empty();
    2. emptyOpt.get();
  2. of(): 如果user为空,会抛出NullPointerException。

  1. Optional<User> opt = Optional.of(user);
  1. ofNullable(): 如果对象即可能是 null 也可能是非 null,你就应该使用 ofNullable() 方法。
    1. Optional<User> opt = Optional.ofNullable(user);

方法

方法 描述
static Optional empty() 返回空的 Optional 实例。
boolean equals(Object obj) 判断其他对象是否等于 Optional。
Optional filter(Predicate<? super predicate) 如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。
Optional flatMap(Function<? super T,Optional> mapper) 如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional
T get() 如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
int hashCode() 返回存在值的哈希码,如果值不存在 返回 0。
void ifPresent(Consumer<? super T> consumer) 如果值存在则使用该值调用 consumer , 否则不做任何事情。
boolean isPresent() 如果值存在则方法会返回true,否则返回 false。
Optional map(Function<? super T,? extends U> mapper) 如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional。
static Optional of(T value) 返回一个指定非null值的Optional。
传递给of()的值不可以为空,否则会抛出空指针异常
static Optional ofNullable(T value) 如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional。
T orElse(T other) 如果存在该值,返回值, 否则返回 other。
T orElseGet(Supplier<? extends T> other) 如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。
T orElseThrow(Supplier<? extends X> exceptionSupplier) 如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
String toString() 返回一个Optional的非空字符串,用来调试

参考

https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
https://blog.woohoo.top/2021/01/About-Java8-Optional-First-Experience/