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是一个很简单但又很实用的工具类,其设计模式是很值得我们学习的

 

posted @   qeDVuHG  阅读(581)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示