在平常开发中经常会遇到需要判空的场景
public
这样判断固然没有错,也可以实现正确的需求,但是有以下两点问题。
1.不优雅
在代码中存在很多==null的判断势必让代码变得丑陋。
2.多层获取对象
看以下场景的事例
String value = param.getCity().getCode().getValue();
这时候只要中间有一个对象为空时,你就会获得一个NullPointerException。如果用传统的if方式来进行判断是这样的
if (param != null) {
if (param.getCity() != null) {
if (param.getCity().getCode() != null) {
String value = param.getCity().getCode().getValue();
}
}
}
非常繁琐,非常难看有木有
Optional就是为了解决以上的问题出现的,其实在JDK8之前已经有第三方的一些工具包也有类似的方案,但是并不怎么流行。
Optional<T>
对于上文提到的第一个场景,如果使用Optional,我们可以这样做
Optional.ofNullable(param).orElse(new Param());
Optional的初始方式有3个方法,分别是:
ofNullable:允许一个可能为空的对象
of:需要一个不为空的对象
这里需要自行判断,初始化的对象是否必然非空。
Optional获取对应值并进行判空的方法有以下几种:
orElse:如果值为空,返回一个对象
orElseGet:如果值为空,执行一段lambda并返回一个对象
orElseThrow:如果值为空,抛出一个异常
这样我们就可以用一行代码进行优雅的判空,并且在为空的情况下进行数据的兜底。
对于上文提到的第二种情况,我们一样可以使用Optional
Optional.ofNullable(param).map(Param::getCity).map(City::getCode).map(Code::getValue).orElse("init")
在上述的代码中使用了map方法,它可以将Optional对应的类型转换为其他类型。
只要在链路上存在一个空值,就会返回一个兜底数据,简化了代码并且还增加了可读性。
其他方法
empty:可以创建一个空的Optional对象
get:直接获取Optional内部对象,但是不建议单独使用
isPresent:判断内部对象是否为空,返回一个布尔值
ifPresent:一样判断内部对象是否为空,如果不为空会执行lambda表达式
filter:通过一定条件过滤对象
flatMap:和map的区别为lambda入参的对象封装入了Optional
参考:
Optional (Java Platform SE 8 )docs.oracle.com