Optional 是 JDK8 中用来改善臭名昭著的 NPE(NullPointer)的重要利器,尤其是搭配 Lambda 表达式的情况下,可以极大的改善以前大量的判空操作,下面我会用使用 Optional 之前和使用 Optional 之后的代码做对比来展现 Optional 的用法和作用,另外,本文需要一定的 Lambda 知识,如果不了解可以先看一下这个《[Lambda 表达式](/posts/java/Lambda 表达式.html)》
Optional.of()方法创建必须保证该对象不为空,否则一样会抛出 NullPointerOptional.ofNullable()方法当对象为空时,不会抛出 NPE,一般除非需要一旦为空需要抛出异常或者上层处理,否则更多的使用ofNullable创建OptionalOptional.empty()该方法会创建一个空的Optional,一般用做返回空的Optioanl方法内部和 JDK 方法内部使用。
Optional.of(obj);
Optional.ofNullable(obj);
ifPresent
ifPresent一般用来代替以前的判空操作,在对象不为空时会执行ifPresend中的代码
- Optional之前
if(null != obj){
System.out.pringln(obj);
}
- Optional之后
Optional.ofNullable(obj).ifPresent(System.out::println);
orElse
orElse一般用来代替三目表达式,对象不为空时返回原对象,对象为空时返回新的对象
- Optional之前
// 这样的
return null == obj?new Obj():obj;
// 或者这样的
if(null == obj) {
return new Obj;
} else {
return obj;
}
- Optional之后
return Optional.ofNullable(obj).orElse(new Obj());
orElseGet
orElseGet ()与orElse ()作用几乎一摸一样,但是需要注意以下的不同点
orElseGet ()接受的参数是Supplier对象,或者说Lambda表达式,而orElse ()的参数是一个对象,这也就导致orElse ()的参数一定会被执行(除非打断或异常之类),例如Optional.ofNullable(obj).orElse(new Obj ());不论obj对象是否为空,都会执行new Obj (),因为new Obj ()是方法的参数,所以在需要性能考虑的地方尽量使用orElseGet ()代替orElse (),orElseGet ()的另一个好处是可以使用Lambda来添加一些额外的功能,例如在obj对象为空时输出一句话
- Optional之前
// 这样的
return null == obj?new Obj():obj;
// 或者这样的
if(null == obj) {
return new Obj;
} else {
return obj;
}
- Optional之后
return Optional.ofNullable(obj).orElseGet(() -> {
System.out.println("obj is null,return a new value");
return new Object();
});
OrElseThrow
对象不为空时返回原对象,对象为空时抛出一个异常
- Optional之前
if(null == obj) {
throw new RuntimeException("the obj is null!");
} else {
return obj;
}
- Optional之后
return Optional.ofNullable(null)
.orElseThrow(() -> new RuntimeException("the obj is null"));
filter
filter ()更多的是用在集合中对元素的筛选或者判断,在Optional中用的并不多,不再过多赘述,需要的可以看下《Lambda表达式》
map
map ()一般用来将对象映射成另一种元素,在Optional中map解决链式调用多重判空的利器,这也是较为常用的一个方法
- Optional之前
//相信大家在工作中或多或少碰到过这样的代码
if( null != student){
//学生不为空获取学生的老师
Teacher teacher = student.getTeacher();
if(null != teacher){
//老师不为空获取老师的地址
String address = teacher.getAddress();
if(null != address){
//地址不为空则输出
System.out.println("the teacher address is "+address);
}
}
}
- Optioanl之后
// 这样是不是简洁了很多呢
Optional.ofNullable(student)
.map(Student::getTeacher)
.map(Teacher::getAddress)
.ifPresend(System.out::pringln);