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是一个很简单但又很实用的工具类,其设计模式是很值得我们学习的
Guava源码学习(一)Optional的更多相关文章
- Guava源码学习(五)EventBus
基于版本:Guava 22.0 Wiki:EventBus 0. EventBus简介 提供了发布-订阅模型,可以方便的在EventBus上注册订阅者,发布者可以简单的将事件传递给EventBus,E ...
- Guava源码学习(二)Ordering
基于版本:Guava 22.0 Wiki:Ordering 0. Ordering简介 Guava的Ordering提供了链式风格的比较器的实现,我们可以用Ordering轻松构建复杂的比较器. 1. ...
- Guava源码学习(零)前言
Guava是由Google出品的Java类库,功能强大且易用. 后续我会用多篇博客介绍Guava的使用方法,以及从源码层面分析其实现原理. 分析次序基于Guava的官方Wiki 基于版本:Guava ...
- Guava源码学习(三)ImmutableCollection
基于版本:Guava 22.0 Wiki:Immutable collections 0. ImmutableCollection简介 类似于JDK的Collections.unmodifiableX ...
- Guava源码学习(四)新集合类型
基于版本:Guava 22.0 Wiki:New collection types 0. 简介 Guava提供了很多好用的集合工具,比如Multiset和BiMap,本文介绍了这些新集合类型的使用方式 ...
- caffe源码学习之Proto数据格式【1】
前言: 由于业务需要,接触caffe已经有接近半年,一直忙着阅读各种论文,重现大大小小的模型. 期间也总结过一些caffe源码学习笔记,断断续续,这次打算系统的记录一下caffe源码学习笔记,巩固一下 ...
- Aspects 源码学习
AOP 面向切面编程,在对于埋点.日志记录等操作来说是一个很好的解决方案.而 Aspects 是一个对于AOP编程的一个优雅的实现,也可以直接借助这个库来使用AOP思想.需要值得注意的是,Aspect ...
- Guava 源码分析(Cache 原理 对象引用、事件回调)
前言 在上文「Guava 源码分析(Cache 原理)」中分析了 Guava Cache 的相关原理. 文末提到了回收机制.移除时间通知等内容,许多朋友也挺感兴趣,这次就这两个内容再来分析分析. 在开 ...
- mongo源码学习(三)请求接收传输层
在上一篇博客中(mongo源码学习(二)db.cpp之mongoDbMain方法分析),我们把db.cpp中的mongoDbMain的执行过程分析了一下,最后会调用initAndListen(serv ...
随机推荐
- laravel5.5授权系统
目录 1. Gates 1.1 一个简单的使用Gates的例子 1.2 编写Gates 1.3 授权动作 2. policy策略 2.1 还是先看个例子 2.2 编写策略 2.3 授权策略 2.3.1 ...
- VSX-5 VSXMusic 编码听音乐
给VS写个扩展来听音乐的说法,缘来已久,这两天做了个初版,使用豆瓣FM,先发出来. 插件现在只做了VS2013的,别的版本有待下一步支持. 现在暂时只有一个Adornment(就是那个有封面的),一个 ...
- 剑指Offer - 九度1390 - 矩形覆盖
剑指Offer - 九度1390 - 矩形覆盖2014-02-05 23:27 题目描述: 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形 ...
- 《Cracking the Coding Interview》——第17章:普通题——题目12
2014-04-29 00:04 题目:给定一个整数数组,找出所有加起来为指定和的数对. 解法1:可以用哈希表保存数组元素,做到O(n)时间的算法. 代码: // 17.12 Given an arr ...
- 【志银】#define lowbit(x) ((x)&(-x))原理详解
分析下列语句 #define lowbit(x) ((x)&(-x)) 可写成下列形式: int Lowbit(x) { return x&(-x); } 例1:x = 1 十进制转二 ...
- NodeJS05
商品分类模块 分类model const mongoose = require('mongoose') const schema = new mongoose.Schema({ name: { typ ...
- Win10 WSL Ubuntu18.04 编译安装MySQL5.7
---恢复内容开始--- 在win10 商店中选择 ubuntu18.04 下载地址 http://dev.mysql.com/downloads/mysql/ wget https://cdn.my ...
- Nginx主要模块常用指令说明
核心模块(Core Modules): 主模块(Main Module):配置和服务器全局有关的一些参数,比如错误日志.进程.权限等 user worker_processes error_logsy ...
- nagios原理及配置详解
1.Nagios如何监控Linux机器 NRPE总共由两部分组成:(1).check_nrpe插件,运行在监控主机上.服务器端安装详见:(2).NRPE daemon,运行在远程的linux主机上(通 ...
- dirname(__FILE__)
dirname() 函数返回路径中的目录部分. __FILE__ :被称为PHP魔术常量,返回当前执行PHP脚本的完整路径和文件名,包含一个绝对路径 dirname(__FILE__) 函数返回的是脚 ...