Optional 类的最大作用就是解决 NULL 的问题。围绕 NULL 产生的问题,一般都是非常让人恼火的,不好定位不好查。使用 Optinoal 类就能避免显式的 NULL 值判断,不但能更简洁还能有效解决 NPE 问题。
举个例子:
// 以往
if(.... == null){
...
}
// 如今
Optional.ofNullable(...).map(...); (.map() 为结合了 Lambda 的操作)
创建
从 Optional 类中的源码可以看到,其两个构造方法都是 private 的,所以不能使用 new Optional() 来进行显示的创建。不过其提供了是三个静态方法,empty()、 of(T value) 、ofNullable(T value),我们使用这三个静态方法就可以来创建 Optional 对象了。
// 空
Optional<String> optStr = Optional.empty()
//非空
Optional<String> optStrNotNull = Optional.of("something...")
//允许为空
Optional<String> optStrNullable = Optional.ofNullable(null);
使用
Optional 含有众多的 AIP 接口,下面选取几个常用的接口来举例说明用法
get()
此方法主要用于返回包装对象的实际值,如果包装对象值为 NULL,则会抛 NoSuchElementException 异常。
isPresent()
此方法主要用于判断包装对象的值是否为非空,如果存在对象就返回 true,否则就返回 false,通过这样就能取代 ... ! = null 的这种判断
Optional<String> opt = Optional.of("hello");
System.out.println(opt.isPresent()); // 输出:true
Optional<String> optOrNull = Optional.ofNullable(null);
System.out.println(opt.isPresent()); // 输出:false
ifPresent()
此方法可以接受一个 Consumer 对象,如果包装对象的值非空,则运行 Consumer 的 accpet() 方法。
在实际使用中,如果我们用 ofNullable() 来创建了一个 optional 对象,那么我们在使用这个对象的时候,就要用 isPresent() 方法来判断是否为空,发现了没有,这不是很蹩脚,从原来的直接判断 ...! = null,换成了 isPresent(),这不单依旧要显示的判空,而且还有脱裤子放💨那味儿了。 ifPresent() 就是我们的最优解。
Optional.of("hello")
.ifPresent(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
}); // print abc
// Lambda
Optional.of("hello").ifPresent(s -> System.out.println(s));
fileter()
此方法可以接收一个 Predicate 对象作为参数,然后用于对 Optional 对象进行过滤,符合条件的话就返回 Optional 对象本身,不符合就返回一个空的 Optional 对象。
最后
在整理资料的时候,有一个观点觉得很中肯。 Optional 的真正的作用,不在于告诉使用者,这个数据,可能为 NULL,而是提供了一个可以把多个结果有可能为 NULL 的操作串起来,最终得到一个有可能为 NULL 的结果的容器。然后基于这个观点下,就很好理解,Optional 其实就是为了描述,函数有可能不返回任何值,同时呢我们还能用链式调用,以减少代码的冗余度。