Optional 是 Java 8 引进的一个新特性,主要是用于缓解Java中臭名昭著的空指针异常问题。
我们回忆一下空指针异常出现的原因是什么?
对于一个变量a,没有对a进行 !=null 判断就直接调用a中的方法会导致空指针异常。
而Optional类解决空指针异常的办法是,使用Optional类包装我们的变量a,然后提供isPresent()等一系列方法来进行空值判断和其他操作。
但是在实际使用中,个人觉得,通过Optional进行包装之后再通过isPresent()方法进行null判断,好像跟直接写if进行null判断没啥太大区别,唯一可能比较好的一点是,使用了Optional会提醒你要进行非空判断。所以到这里,好像没有感觉到Optional在处理空指针问题上特别好的地方。
但是得益于Optional提供的各种方法,在某些场景的需求上,使用Optional还是会比较优雅的。比如有如下需求:
获取A->B->C->name的值,中间有任意一个属性为null就返回默认值,我们可以通过下述代码体验下,在链式获取属性值的需求中,使用Optional带来的方便。
public class OptionalTest {
public static void main(String[] args) {
A a = OptionalTest.getA();
//需求:获取A->B->C->name的值,中间有任意一个属性为null就返回默认值
//1、传统判空方法
System.out.println(OptionalTest.getName1(a));
//2、传统判空方法
System.out.println(OptionalTest.getName2(a));
//3、Optional方法
System.out.println(OptionalTest.getName3(a));
}
public static String getName1(A a) {
if (a != null) {
B b = a.getB();
if (b != null) {
C c = b.getC();
if (c != null) {
return c.getName();
}
}
}
return "默认值";
}
public static String getName2(A a) {
if (a != null && a.getB() != null && a.getB().getC() != null) {
return a.getB().getC().getName();
}
return "默认值";
}
public static String getName3(A a) {
return Optional.ofNullable(a)
.map(A::getB)
.map(B::getC)
.map(C::getName)
.orElse("默认值");
}
public static A getA() {
A a = new A();
B b = new B();
C c = new C();
c.setName("小明");
b.setC(c);
a.setB(b);
return a;
}
}
@Data
class A{
private B b;
}
@Data
class B{
private C c;
}
@Data
class C{
private String name;
}
通过3个getName方法的对比,在链式获取属性值的需求上,使用Optional还是比较方便的。