Optional在链式取值中防止“空指针异常”的用法

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还是比较方便的。


觉得内容还不错?打赏个钢镚鼓励鼓励!!👍