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

  • 相关阅读:
    TCP连接异常断开检测(转)
    正排索引与倒排索引(转)
    Elasticsearch之优化
    把网卡中断绑定到CPU,最大化网卡的吞吐量(转)
    十张GIFs让你弄懂递归等概念
    二维数组回形遍历(转)
    如何做Go的性能优化?(转)
    Go的50度灰:Golang新开发者要注意的陷阱和常见错误(转)
    Nginx配置之负载均衡、限流、缓存、黑名单和灰度发布(转)
    从零到卓越:京东客服即时通讯系统的技术架构演进历程(转)
  • 原文地址:https://www.cnblogs.com/stevenczp/p/7268146.html
Copyright © 2020-2023  润新知