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

Guava源码学习(一)Optional的更多相关文章

  1. Guava源码学习(五)EventBus

    基于版本:Guava 22.0 Wiki:EventBus 0. EventBus简介 提供了发布-订阅模型,可以方便的在EventBus上注册订阅者,发布者可以简单的将事件传递给EventBus,E ...

  2. Guava源码学习(二)Ordering

    基于版本:Guava 22.0 Wiki:Ordering 0. Ordering简介 Guava的Ordering提供了链式风格的比较器的实现,我们可以用Ordering轻松构建复杂的比较器. 1. ...

  3. Guava源码学习(零)前言

    Guava是由Google出品的Java类库,功能强大且易用. 后续我会用多篇博客介绍Guava的使用方法,以及从源码层面分析其实现原理. 分析次序基于Guava的官方Wiki 基于版本:Guava ...

  4. Guava源码学习(三)ImmutableCollection

    基于版本:Guava 22.0 Wiki:Immutable collections 0. ImmutableCollection简介 类似于JDK的Collections.unmodifiableX ...

  5. Guava源码学习(四)新集合类型

    基于版本:Guava 22.0 Wiki:New collection types 0. 简介 Guava提供了很多好用的集合工具,比如Multiset和BiMap,本文介绍了这些新集合类型的使用方式 ...

  6. caffe源码学习之Proto数据格式【1】

    前言: 由于业务需要,接触caffe已经有接近半年,一直忙着阅读各种论文,重现大大小小的模型. 期间也总结过一些caffe源码学习笔记,断断续续,这次打算系统的记录一下caffe源码学习笔记,巩固一下 ...

  7. Aspects 源码学习

    AOP 面向切面编程,在对于埋点.日志记录等操作来说是一个很好的解决方案.而 Aspects 是一个对于AOP编程的一个优雅的实现,也可以直接借助这个库来使用AOP思想.需要值得注意的是,Aspect ...

  8. Guava 源码分析(Cache 原理 对象引用、事件回调)

    前言 在上文「Guava 源码分析(Cache 原理)」中分析了 Guava Cache 的相关原理. 文末提到了回收机制.移除时间通知等内容,许多朋友也挺感兴趣,这次就这两个内容再来分析分析. 在开 ...

  9. mongo源码学习(三)请求接收传输层

    在上一篇博客中(mongo源码学习(二)db.cpp之mongoDbMain方法分析),我们把db.cpp中的mongoDbMain的执行过程分析了一下,最后会调用initAndListen(serv ...

随机推荐

  1. centos使用--排查服务是否可用

    端口与服务的关系 一台拥有IP地址的主机可以提供许多服务,比如Web服务.FTP服务.SMTP服务等,这些服务完全通过1个IP地址来实现.那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因 ...

  2. leetcode 【 Remove Duplicates from Sorted List 】 python 实现

    题目: Given a sorted linked list, delete all duplicates such that each element appear only once. For e ...

  3. http客户端缓存

    这篇文章写得比较,点击查看

  4. css 之 border-radius属性

    css中给盒子设置圆角可以通过 border-radius 属性来实现(具体原理就不深入探讨了); 在开发过程中都会遇到浏览器兼容问题,这问题其实也不难解决,无非就是加上私有前缀,在这里先忽略掉.   ...

  5. Python面试题之一:解密

    Python面试题之一: 说明:就是Python工程师面试题 一.字典转换与正则提取值 1:key与Value交换 a = {'a':1,'b':2} print({value:key for key ...

  6. 【志银】NYOJ《题目860》又见01背包

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=860 方法一:不用滚动数组(方法二为用滚动数组,为方法一的简化) 动态规划分析:最少要拿总 ...

  7. PAT——甲级1042:Shuffling Mashine

    终于做到甲级了 就一个感觉....题目是真的看不懂,亏我还是四六级都过了的人....可是看完题愣是一点都不懂是什么意思. 1042 Shuffling Machine (20 point(s)) Sh ...

  8. class内部处理

    class A { public: int foo( ) { return val ; } static int staFun( ) { return staVal ; } static int st ...

  9. ajax-高设3

    ajax 1.XHR Ajax 技术的核心是 XMLHttpRequest 对象(简称 XHR),这是由微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现.在 XHR 出现之前,Ajax ...

  10. (转)彻底隐藏Nginx版本号的安全性与方法

    Nginx默认是显示版本号的,如: [root@bkjz ~]# curl -I www.nginx.orgHTTP/1.1 200 OKServer: nginx/0.8.44Date: Tue, ...