用Optional取代null
- 一、为什么要使用Optional?
- 二、Optional API
-
- 1.创建Optional对象
-
- 1.1 创建一个空的Optional对象
- 1.2 根据参数创建Optional对象
- 1.3 可接收null的Optional对象
- 2. 解引用Optional对象
-
- 2.1 get()
- 2.2 orElse(T other)
- 2.3 orElseGet(Supplier<? extends T> other)
- 2.4 orElseThrow(Supplier<? extends X>exceptionSupplier)
- 2.5 ifPresent(Consumer<? super T>)
积羽沉舟,群轻折轴,众口铄金,积毁销骨。
羽毛虽轻,堆积多了也能把船压沉,一大堆不重的东西,堆积多了也能压断车轴,众人异口同声的言论,能够混淆是非,不止一次的诽谤,积累下来也足以致人于毁灭之地。
一、为什么要使用Optional?
Optional是java8为核心类库新设计的一个数据类型,用来替换null值。我们常用null来表示值不存在,但这样做最大的问题在于NullPointerException,一旦引用一个存储null值的变量,程序会立即崩溃。为了消除null给我们带来的困扰,java8引入了Optional。
二、Optional API
1.创建Optional对象
1.1 创建一个空的Optional对象
1.2 根据参数创建Optional对象
需要注意的是,如果参数值是一个null,下面的代码会立即抛出一个NullPointerException,而不是等到你试图获取值时才返回一个错误。
// 会抛出空指针异常
Optional<Object> o = Optional.of(null);
1.3 可接收null的Optional对象
如果参数是null,那么得到的Optional对象就是个空对象。
// 得到一个空的Optional对象
Optional<Object> o = Optional.ofNullable(null);
2. 解引用Optional对象
2.1 get()
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
get()是这些方法中最简单但又最不安全的方法。如果变量存在,它直接返回封装的变量值,否则就抛出一个NoSuchElementException异常。除非,你非常确定Optional变量一定包含值。
2.2 orElse(T other)
public T orElse(T other) {
return value != null ? value : other;
}
这个方法允许你在Optional对象不包含值时提供一个默认值。
2.3 orElseGet(Supplier<? extends T> other)
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
orElseGet(Supplier<? extends T> other)是orElse方法的延迟调用版,Supplier方法只有在Optional对象不含值时才执行调用。如果创建默认值是件耗时费力的工作,你应该考虑采用这种方式(借此提升程序的性能),或者你需要非常确定某个方法仅在Optional为空时才进行调用,也可以考虑该方式(这种情况有严格的限制条件)。
2.4 orElseThrow(Supplier<? extends X>exceptionSupplier)
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
orElseThrow(Supplier<? extends X>exceptionSupplier)和get方法非常类似,它们遭遇Optional对象为空时都会抛出一个异常,但是使用orElseThrow你可以定制希望抛出的异常类型。
2.5 ifPresent(Consumer<? super T>)
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
ifPresent(Consumer<? super T>)让你能在变量值存在时执行一个作为参数传入的方法,否则就不进行任何操作。