Java从1.8开始,引入一个class Optional<T>(java.util.Optional<T>)。它继承于java.lang.Object。
Java官方文档写着:
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
首先我们来聊聊null。null在java中是一个关键字,用来标识一个不确定的对象。我们在使用引用型变量时,如果只定义了变量,没有初始化它,默认值就是null。比如说下面这个set就是只被定义,没有被赋值:
Set<Integer> mySet;
这样就面临一个问题,当我们试图去处理这个变量的时候,可能会有NullPointer Exception。
此外,像List, Set, Map等Collection允许null存在:
- List:可以加入任意多个null。
- Set:最多可以加入一个null。
- Map:Map的key最多可以加入一个null,value字段没有限制。
- 数组:引用类型数组,不给定初始值,则所有的元素值为null(基本类型数组有非null的默认值)。
当我们在使用这些Collection时,也容易出现各种因为没有考虑null而引发的异常。
Java 8里的Optional可以简化null的检查。比如下面的code:
class Outer {
Nested nested;
}
class Nested {
Inner inner;
}
class Inner {
String foo;
}
在Java 8以前,我们会这么用:
Outer outer = new Outer();
if (outer != null && outer.nested != null && outer.nested.inner != null) {
System.out.println(outer.nested.inner.foo);
}
现在,我们只需要:
Optional.of(new Outer())
.flatMap(o -> Optional.ofNullable(o.nested))
.flatMap(n -> Optional.ofNullable(n.inner))
.flatMap(i -> Optional.ofNullable(i.foo))
.ifPresent(System.out::println);
每一次.flatMap
都会返回一个Optional来包着(wrapping)需要的object或者null。
Optional.ofNullable(x): Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.
如果是null,返回一个用Optional表示的null;如果不是null,返回wrap这个value的Optional。
下面具体介绍一下常用的几个method:
- flatMap(Function<? super T,Optional<U>> mapper)
如果Optional包裹的value存在,运行mapper这个function,并返回结果(结果也用Optional包着),否则返回empty Optional。
返回类型:<U> Optional<U> - isPresent()
判断是否存在value,是则返回true。
返回类型:boolean - get()
如果存在value,返回value值;否则返回NoSuchElementException。
返回类型:T(value的类型)
...
当然,相比于null,Optional会更占空间。