Java 8 的Optional对NullPointException的处理

在没用Optional之前我们在获取对象的时候需要大量的类似 if(null!=user)的判断。java8通过Optional对该问题进行优化。
首先我们初始化相关类

  • 初始化 User类
import java.util.StringJoiner;

public class User {
    /**用户姓名. */
    private String name;
    /**用户年龄. */
    private Integer age;
    /**用户地址. */
    private Address address;

    public User() {

    }
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public User(String name, Integer age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", User.class.getSimpleName() + "[", "]")
                .add("name='" + name + "'")
                .add("age=" + age)
                .add("address=" + address)
                .toString();
    }
}

  • 初始化Address类
import java.util.StringJoiner;

public class Address {
    /**地址编号. */
    private String code;
    /**地址名称. */
    private String name;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", Address.class.getSimpleName() + "[", "]")
                .add("code='" + code + "'")
                .add("name='" + name + "'")
                .toString();
    }
}

  • 最后演示Optional在各种场景下的应用
import java.util.Optional;
import java.util.function.Supplier;

/**
 * 参考:https://mp.weixin.qq.com/s/54fTuplkTbLV1ldsVVUSwg
 * <p>
 * 总结:代码以简单易懂为主,做到能够平衡
 */
public class Test {

    public static User initUser() {
        Address address = new Address();
        address.setCode("001");
        address.setName("大连");

        User user = new User();
        user.setName("Andy");
        user.setAge(30);
        user.setAddress(address);
        return user;
    }

    public static void main(String[] args) {

        User user = initUser();

        //1.如果用户不为空返回对象,否则创建一个对象
        User user1 = Optional.ofNullable(user).orElse(new User());
        System.out.println("user1:" + user1);//user1:User[name='Andy', age=30, address=Address[code='001', name='大连']]

        user = null;
        user1 = Optional.ofNullable(user).orElse(new User());
        System.out.println("user1:" + user1);//user1:User[name='null', age=null, address=null]

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //2.返回对象的值(如果value不为空则做返回,如果为空则抛出异常 "No value present)
        User user2 = Optional.ofNullable(user).get();
        System.out.println("user2:" + user2);//user2:User[name='Andy', age=30, address=Address[code='001', name='大连']]

        //测试时候打开下面的注释
        //user = null;
        user2 = Optional.ofNullable(user).get();
        System.out.println("user2:" + user2);//Exception in thread "main" java.util.NoSuchElementException: No value present

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //3.判读是否为空(如果对象不为空则为真,如果为空则false)
        boolean user3 = Optional.ofNullable(user).isPresent();
        System.out.println("user3:" + user3);

        user = null;
        user3 = Optional.ofNullable(user).isPresent();
        System.out.println("user3:" + user3);

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //4.判读是否为空并返回函数(如果对象非空,则运行函数体,如果对象为空,则不执行函数体)
        Optional.ofNullable(user).ifPresent(u -> System.out.println("user4:" + u)); //user4:User[name='Andy', age=30, address=Address[code='001', name='大连']]

        user = null;
        Optional.ofNullable(user).ifPresent(u -> System.out.println("user4:" + u));

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //5.过滤对象(接受一个对象,然后对他进行条件过滤,如果条件符合则返回Optional对象本身,如果不符合则返回空Optional)
        Optional<User> user5 = Optional.ofNullable(user).filter(u -> u.getAge() > 10);
        System.out.println("user5:" + user5); //Optional[User[name='Andy', age=30, address=Address[code='001', name='大连']]]
        System.out.println("user5:" + user5.isPresent());//true

        user5 = Optional.ofNullable(user).filter(u -> u.getAge() > 100);
        System.out.println("user5:" + user5); //Optional.empty
        System.out.println("user5:" + user5.isPresent());//false

        user = null;
        user5 = Optional.ofNullable(user).filter(u -> u.getAge() > 10);
        System.out.println("user5:" + user5);//Optional.empty
        System.out.println("user5:" + user5.isPresent());//false

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //6.对象进行二次包装(将对应Function函数式接口中的对象,进行二次运算,封装成新的对象然后返回在Optional中)
        String user6 = Optional.ofNullable(user).map(u -> u.getName()).orElse("name为空");
        System.out.println("user6:" + user6);//user6:Andy
        user = null;
        user6 = Optional.ofNullable(user).map(u -> u.getName()).orElse("name为空");
        System.out.println("user6:" + user6);//user6:name为空

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //7。Optional对象进行二次包装(将对应Optional< Funcation >函数式接口中的对象,进行二次运算,封装成新的对象然后返回在Optional中)
        Optional<String> user7 = Optional.ofNullable(user).map(u -> Optional.ofNullable(u.getName()).orElse("name为空"));
        System.out.println("user7:" + user7);//user7:Optional[Andy]
        System.out.println("user7:" + user7.get());//user7:Andy

        //测试时候打开下面的注释
        //user = null;
        user7 = Optional.ofNullable(user).map(u -> Optional.ofNullable(u.getName()).orElse("name为空"));
        System.out.println("user7:" + user7);//user7:Optional.empty
        System.out.println("user7:" + user7.get());//Exception in thread "main" java.util.NoSuchElementException: No value present

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //8.为空返回对象(如果包装对象为空的话,就执行orElse方法里的value,如果非空,则返回写入对象)
        User user8 = Optional.ofNullable(user).orElse(new User("小明", 2));
        System.out.println("user8:" + user8);//user8:User[name='Andy', age=30, address=Address[code='001', name='大连']]

        user = null;

        user8 = Optional.ofNullable(user).orElse(new User("小明", 2));
        System.out.println("user8:" + user8);//user8:User[name='小明', age=2, address=null]

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //9.为空返回Supplier对象(这个与orElse很相似,入参不一样,入参为Supplier对象,为空返回传入对象的.get()方法,如果非空则返回当前对象)
        Optional<Supplier<User>> optionalUserSupplier = Optional.ofNullable(User::new);
        //调用get()方法,此时才会调用对象的构造方法,即获得到真正对象
        User user9 = Optional.ofNullable(user).orElseGet(optionalUserSupplier.get());
        System.out.println("user9:" + user9);//user9:User[name='Andy', age=30, address=Address[code='001', name='大连']]

        user = null;
        user9 = Optional.ofNullable(user).orElseGet(optionalUserSupplier.get());
        System.out.println("user9:" + user9);//user9:User[name='null', age=null, address=null]

        System.out.println("-----------------------------------------------------------------------------------------");

        user = initUser();
        //10.为空返回异常(如果为空,就抛出你定义的异常,如果不为空返回当前对象)
        User user10 = Optional.ofNullable(user).orElseThrow(() -> new RuntimeException("没有查询的相关数据"));
        System.out.println("user10:" + user10);//user10:User[name='Andy', age=30, address=Address[code='001', name='大连']]

        user = null;
        user10 = Optional.ofNullable(user).orElseThrow(() -> new RuntimeException("没有查询的相关数据"));
        System.out.println("user10:" + user10);//Exception in thread "main" java.lang.RuntimeException: 没有查询的相关数据
    }
}

原文地址:https://www.cnblogs.com/chenjianfei/p/13851724.html