创建Optional实例(以下都是静态方法):
Optional.of(T) 创建指定引用的Optional实例,若引用为null则快速失败
Optional.absent() 创建引用缺失的Optional实例
Optional.fromNullable(T) 创建指定引用的Optional实例,若引用为null则表示缺失
用Optional实例查询引用(以下都是非静态方法):
boolean isPresent() 如果Optional包含非null的引用(引用存在),返回true
T get() 返回Optional所包含的引用,若引用缺失,则抛出java.lang.IllegalStateException
T or(T) 返回Optional所包含的引用,若引用缺失,返回指定的值
T orNull() 返回Optional所包含的引用,若引用缺失,返回null
Set asSet() 返回Optional所包含引用的单例不可变集,如果引用存在,返回一个只有单一元素的集合,如果引用缺失,返回一个空集合。
根据源码可知:
Optional类为抽象类,他的实现类有两个,分别为Present和Absent;
final class Present extends Optional {
private final T reference;
Present(T reference) {
this.reference = reference;
}
}
final class Absent extends Optional {
static final Absent INSTANCE = new Absent();
static Optional withType() {
return INSTANCE;
}
private Absent() { }
}
Optional使用入口:
而真正使用Optional类时应该调用他的三个静态实例化方法实例化方法:
public abstract class Optional implements Serializable {
//创建引用缺失的
Optional public static Optional absent() {
return Absent.withType();
}
//创建指定引用的Optional实例,若引用为null则快速失败
public static Optional of(T reference) {
return new Present(Preconditions.checkNotNull(reference));
}
//创建指定引用的Optional实例,若引用为null则表示缺失
public static Optional fromNullable(@Nullable T nullableReference) {
return (Optional)(nullableReference == null?absent():new Present(nullableReference));
}
Optional() { }
}
接下来继续看源码,为什么absent()方法创建的就是缺失的?
由absent()方法可以看到返回的是Absent类中的静态方法withType(),而withType()返回的是一个Absent对象,这个Absent中并没有加入任何其他类,所以它所代表的就是null的引用
final class Absent extends Optional {
static final Absent INSTANCE = new Absent();
static Optional withType() {
return INSTANCE;
}
}
而Absent()类中的其他方法全部这对这个null引用进行重写。
为什么of方法创建的就是指定的Optional实例,为null则快速失败?
public static Optional of(T reference) {
return new Present(Preconditions.checkNotNull(reference));
}
查看Optional类的of(T reference)方法可以看到,返回了一个新建的Present对象,在初始化Present对象时参数为Preconditions类中checkNotNull()方法进行验证reference,如checkNotNull()所示,如果reference引用为null,则会抛出异常,如果不为null,则直接返回reference引用,然后在Present类中进行操作。
public static T checkNotNull(T reference) {
if(reference == null) {
throw new NullPointerException();
} else {
return reference;
}
}
为什么Optional类的fromNullable(@Nullable T nullableReference)可以指定引用的Optional实例,若引用为null则表示缺失?
public static Optional fromNullable(@Nullable T nullableReference) {
return (Optional)(nullableReference == null?absent():new Present(nullableReference));
}
由源码可以看到 fromNullable方法在进行实例化时,对传入的引用参数进行了null判断,如果为null则实例化Absent对象,如果不为null,则实例化Present对象。
Optional类常用方法:
boolean isPresent() 如果Optional包含非null的引用(引用存在),返回true
在Absent类中isPresent()方法直接返回false
在Present类中isPresent()方法直接返回true
T get(e) 返回Optional所包含的引用,若引用缺失,则抛出java.lang.IllegalStateException
在Absent类中get(e)直接跑出异常
public T get() {
throw new IllegalStateException("Optional.get() cannot be called on an absent value");
}
在Present类中get方法直接讲引用返回
public T get() {
return this.reference;
}
T or(T) 返回Option所包含的引用,若引用缺失,返回指定的值
在创建时已经确定Present类中代表着非缺失的类,Absent代表着缺失的类。
所以Present类中or(T)实现的方式为先检验传入的参数是否为null,然后直接返回当前值:
public T or(T defaultValue) {
Preconditions.checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
return this.reference;
}
Absent类中or(T)实现的方式为直接校验传入的参数,如果参数不为空则直接返回参数
public T or(T defaultValue) {
return Preconditions.checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
}
T orNull() 返回Optional所包含的引用,若引用缺失,返回null
同get设计
Present直接返回当前所包含的引用
Absent直接返回null
Set<T> asSet() 返回Optional所包含引用的单例不可变集,如果引用存在,返回一个只有单一元素的集合,如果引用缺失,返回一个空集合
Present最终实现了一个singleton类
private static class SingletonSet<E>
extends AbstractSet<E>
implements Serializable {
private static final long serialVersionUID = 3193687207550431679L;
private final E element;
SingletonSet(E e) {element = e;}
public Iterator<E> iterator() {
return singletonIterator(element);
}
public int size() {return 1;}
public boolean contains(Object o) {return eq(o, element);}
}
Absent则返回一个空集合,即最终新建了一个new EmptySet<>()类
这里在介绍一个在Optional类当中使用最多的一个方法Preconditions.checkNotNull(),这个方法在Preconditions类中有很多中重载方式,这里就不一一介绍了,详情在介绍Preconditions类中会有说明,因为Optional类中用的最多的是以下两个方法,所以本节只针对以下两个方法进行说明:
public static <T> T checkNotNull(T reference) {
if(reference == null) {
throw new NullPointerException();
} else {
return reference;
}
}
public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) {
if(reference == null) {
throw new NullPointerException(String.valueOf(errorMessage));
} else {
return reference;
}
}
看到两个函数的源码,很快就会明白这个函数到底是干什么的,对传入的引用进行判空处理,如果当前引用为null则会抛出 NullPointerException异常,否则返回当前引用。