从语义上,可以把它们当作一回事儿,但是实际中它们之间的差别非常大:如果你尝试引用一个null,一定会触发NullPointerException,不过使用 Optional.empty()就完全没事,它是Optional类的一个有效对象,多种场景都能调用,非常有用
应用Optional的几种模式 声明一个空的:Optional Optional<Car> optCar = Optional.empty(); 依据一个非空值创建:Optional Optional<Car> optCar = Optional.of(car); 可接受null的Optional: Optional<Car> optCar = Optional.ofNullable(car); 用filter过滤满足条件的判断: //使用Optional前: //Insurance insurance = ...; if(insurance != null && "CambridgeInsurance".equals(insurance.getName())){ System.out.println("ok"); } //使用Optional后: //Optional<Insurance> optInsurance = ...; optInsurance.filter(insurance -> "CambridgeInsurance".equals(insurance.getName())) .ifPresent(x -> System.out.println("ok")); 使用map从Optional对象中提取和转换值: //使用Optional前: if(insurance != null){ name = insurance.getName(); } //使用Optional后: Optional<String> name = Optional.ofNullable(insurance).map(Insurance::getName) 使用flatmap从Optional对象中提取和转换值(多级嵌套对象): //使用Optional前: public String getCarInsuranceNameWithDefensiveInspection(Person person) { if (Objects.nonNull(person)) { Car car = person.getCar(); if (Objects.nonNull(car)) { Insurance insurance = car.getInsurance(); if (Objects.nonNull(insurance)) { return insurance.getName(); } } } return "Unkown"; } //使用Optional后: Optional.ofNullable(person) .flatMap(Person::getCar) .flatMap(Car::getInsurance) .map(Insurance::getName) .orElse("Unkown"); 获取Optional中引用的对象 //get()是这些方法中最简单但又最不安全的方法 public T get() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; } //orElse(T other)它允许你在 Optional对象不包含值时提供一个默认值 public T orElse(T other) { return value != null ? value : other; } //orElseGet(Supplier<? extends T> other)是orElse方法的延迟调用版,Supplier 方法只有在Optional对象不含值时才执行调用 public T orElseGet(Supplier<? extends T> supplier) { return value != null ? value : supplier.get(); } //orElseThrow(Supplier<? extends X> exceptionSupplier)和get方法非常类似, 它们遭遇Optional对象为空时都会抛出一个异常,但是使用orElseThrow你可以定制希望抛出的异常类型 public T orElseThrow() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; } //ifPresent(Consumer<? super T>)让你能在变量值存在时执行一个作为参数传入的 方法,否则就不进行任何操作 public void ifPresent(Consumer<? super T> action) { if (value != null) { action.accept(value); } } 在域模型中使用Optional,以及为什么它们无法序列化Optional的设计初衷仅仅是要支持能返回Optional对象的语法,由于Optional类设计时就没特别考虑将其作为类的字段使用,所以它也并未实现 Serializable接口,由于这个原因,如果应用使用了某些要求序列化的库或者框架,在 域模型中使用Optional,有可能引发应用程序故障
//model中的替代方案 public class Person { private Car car; public Optional<Car> getCarAsOptional() { return Optional.ofNullable(car); } }完整代码地址:https://github.com/BoyQiang/personal-code-learning/blob/master/personal-code-learning-customer/src/main/java/com/personal/code/biz/CarBizIml.java