Lambda从入门到精通之二十二 Optional类

Java 8中引入了一个新的类java.util.Optional<T> ,Optional类是一个容器类,代表一个值存在或不存在,这一个特性就可以帮助我们解决Java程序员最常见的NullPointerException

怎样产生的空指针异常

我们有一个Person类,Person中又定义了一个Address类,代码:

@Data
public class Person {
    private String name;
    private int age;
    private Address address;
}

@Data
public class Address {
    private String addressInfo;
}

如果我们执行下面的代码:

public class OptionalClient {

    public static void main(String[] args) {
        Person person = new Person();
        person.getAddress().getAddressInfo();
    }
}

则会得到空指针异常:

Exception in thread "main" java.lang.NullPointerException
	at com.itzhimei.study.lambda.OptionalClient.main(OptionalClient.java:11)

空指针异常就是应用了未定义的对象中的属性,则会产生空指针异常。

怎样使用Optional消除空指针异常

不使用Optional,我们之前的做法就是使用if来判断person是否为空,address是否为空,不为空则调用address的属性。

我们先对Person中的Address进行一点小修改:

@Data
public class Person2 {
    private String name;
    private int age;
    private Optional<Address> address;
}

我们将Address用Optional封装起来,此时Person的Address就变成了一个Optional容器。

测试类代码:

public class OptionalClient2 {

    public static void main(String[] args) {
        Person2 person2 = new Person2();
        person2.setAddress(Optional.empty());
        Optional<Address> address = person2.getAddress();
        boolean present = address.isPresent();
        Address address1 = address.orElse(new Address());
        Address address2 = address.get();
    }
}

我们使用Person的对象获取Address,返回类型已经变成了Optional<Address>,这个返回类型是一个容器,通过调用isPresent()方法,判断Optional中的值(Address)如果非空,返回true,否则返回false。

orElse()方法其实相当于一个三目运算符:

address !=null ? address:new Addrsss()

get()方法就是提取Optional<Address>中的Address对象,如果为空,也会产生java.util.NoSuchElementException异常,所以我们上面说的是合理使用Optional会避免空指针异常。