简介
java 1.8引入java.util.Optional类可以更优雅的替代空值判断,减少代码中的空指针异常。可以当作一个特殊的集合数据,至多包含一个元素。Optional可以是包含T类型对象或者空的Optional对象,设计初衷仅仅是支持能返回Optional对象的语法,所以引入该语法并非是完全消除null引用。
类的方法
| 方法 | 描述 |
|---|---|
| empty | 返回空的Optional实例 |
| of | 创建Optional,参数不能为null |
| ofNullable | 创建Optional,参数可以为null |
| get | 存在值,Optional封装返回,不存在,会抛出NoSuchElementException异常 |
| isPresent | 判断值是否存在 |
| ifPresent | 值存在,执行该值方法调用,否则不调用 |
| filter | 判断是否满足Predicate,满足返回该值的Optional对象,否则返回空的Optional对象 |
| map | 值存在,执行提供的函数调用 |
| flatMap | 与map功能相似,区别是map可以返回任何类型的返回值T,flatMap只能返回Optional类型 |
| orElse | 值存在返回该值,不存在返回默认值,不管Optional有没有值都会调用 |
| orElseGet | orElse方法的延迟调用版,只有在Optional对象不含值的时候才会调用 |
| orElseThrow | 值不存在抛出定制类型异常 |
Optional的使用
1.空值的判断
如下代码获取程序名方法使用Optional替换null引用判断:
public static String getProgramName(Program p){
Optional<Program> program = Optional.ofNullable(p);
if(!program.isPresent()){
return "UnKnow";
}
return p.getName();
}
获取程序名的时候,利用isPresent()方法判断是否存在来替代null引用空判断,并未更简洁,不建议这样写,我们进一步使用Optional进行改写,代码如下:
public static String getProgramName(Program p){
return Optional.ofNullable(p)
.map(item-> item.getName())
.orElse("UnKnow");
}
2.过滤值和链式调用
如果我们想查询某一产品(idea产品)的程序名,如下代码:
public static String getProgramName(Product product){
return Optional.ofNullable(product)
.filter(item->item.getName().equals("idea"))
.map(Product::getProject)
.map(Project::getProgram)
.map(Program::getName).orElse("unKnow");
}
利用Optional进行处理会变的很清晰,可读性更强。如果进行null引用的判断,会嵌套很多的if条件语句或者每次判空进行返回,都会显得有些复杂,不利于后期维护。 当然还有其它场景可以进行null引用优化,另外需要注意的是Optional并未实现Serializable接口,因此不能作为类的字段,否则在使用有序列化要求的库或者框架会出现问题。
总结
1.使用Optional会有助于我们设计更好的API,有效的防止代码中出现的空指针异常。
2.我们在使用的时候要注意Optional目的只是能返回Optional对象的语法
参考书籍:《java8实战》