Guava源码学习(一)Optional
基于版本:Guava 22.0
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是一个很简单但又很实用的工具类,其设计模式是很值得我们学习的