Guava源码解析一:Optional源码分析

创建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异常,否则返回当前引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值