Guava源码学习(一)Optional

基于版本:Guava 22.0

Wiki:Using and avoiding null

0:Optional简介

null在很多场景下会引发问题,NullPointerException困扰过无数的程序员,Guava用快速失败的思路来显式的解决null问题

ps:JDK1.8也提供了Optional工具包

1. 类图

2. 设计思路

抽象类Optional有两个子类Absent与Present,Optional本身不保存对象,这两个子类才是对象的容器

Absent表示值为null的情况

Present表示值不为null的情况

如果对Absent调用get方法,则会直接抛出IllegalStateException异常

用这样的手段,Optional显式的解决了null问题

3. 构造方法

Optional与它的两个子类的构造器都是私有的,只能通过Optional的几个方法来构造对象

Optional.absent()
  public static <T> Optional<T> absent() {
    return Absent.withType();
  }

Absent.withType()
  static final Absent<Object> INSTANCE = new Absent<Object>();

  @SuppressWarnings("unchecked") // implementation is "fully variant"
  static <T> Optional<T> withType() {
    return (Optional<T>) INSTANCE;
  }

可以很清楚的看出,Optional.absent方法只是返回Absent内置的一个标记对象罢了

Optional.of()
  public static <T> Optional<T> of(T reference) {
    return new Present<T>(checkNotNull(reference));
  }

Optional.checkNotNull
  @CanIgnoreReturnValue
  public static <T> T checkNotNull(T reference) {
    if (reference == null) {
      throw new NullPointerException();
    }
    return reference;
  }

Present()
  private final T reference;

  Present(T reference) {
    this.reference = reference;
  }

Optional.of方法会先对传入的参数进行校验,null会引发异常,不为null的话才会用Present进行包装

  public static <T> Optional<T> fromNullable(@Nullable T nullableReference) {
    return (nullableReference == null)
        ? Optional.<T>absent()
        : new Present<T>(nullableReference);
  }

Optional.fromNullable方法,如果传入值是null,会返回Absent,否则返回包装后的Present对象

4. get方法

Optional.get()
  public abstract T get();

Absent.get()
  @Override
  public T get() {
    throw new IllegalStateException("Optional.get() cannot be called on an absent value");
  }

Present.get()
  @Override
  public T get() {
    return reference;
  }

Optional的get方法是抽象的,具体实现在子类中完成

Absent.get方法会直接抛出异常

Present.get方法会返回内部保存的值

由此实现了在value为null时,调用get方法会快速失败的语义

5. or方法

Optional.or()
  public abstract T or(T defaultValue);

Absent.or()
  @Override
  public T or(T defaultValue) {
    return checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
  }

Present.or()
  @Override
  public T or(T defaultValue) {
    checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
    return reference;
  }

跟get方法相同的套路,相当于一个在value为null的时候返回默认值的get方法

6.orNull方法

Optional.orNull()
  @Nullable
  public abstract T orNull();


Absent.orNull()
  @Override
  @Nullable
  public T orNull() {
    return null;
  }


Present.orNull()
  @Override
  public T orNull() {
    return reference;
  }

同上,相当于一个在value为null时就返回null的get方法

7. 总结

Optional是一个很简单但又很实用的工具类,其设计模式是很值得我们学习的

原文地址:https://www.cnblogs.com/stevenczp/p/7268146.html