Optional

作者: 请叫我铁臂阿童木 | 来源:发表于2019-06-20 15:35 被阅读0次

背景

public class Person {
     private Car car;
     public Car getCar() { return car; }
}
public class Car {
     private Insurance insurance;
     public Insurance getInsurance() { return insurance; }
}
public class Insurance {
    private String name;
    public String getName() { return name; }
} 

针对上述定义,下列代码有何隐患?

public String getCarInsuranceName(Person person) {
    return person.getCar().getInsurance().getName();
}

若person.getCar()或者person.getCar().getInsurance()为空,那么会抛出空指针引用。为避免这种隐患,我们可能会采用防御式编程,层层嵌套if语句进行判断。现在我们可以不必这样做,因为java8引入了一个新的类Optional,用来代替null。

使用

  • 创建Optional对象的三种方式:
  1. 声明一个空的Optional
Optional<Car> optCar = Optional.empty();
  1. 依据一个非空值创建Optional
Optional<Car> optCar = Optional.of(car);
  1. 可接受nullOptional
Optional<Car> optCar = Optional.ofNullable(car);
// 每次你希望安全地对潜在为null的对象进行转换,将其替换为Optional对象时,都可以考 虑使用这种方法
  • 从Optional中获取值的方式

例:从Insurance中获取name

Optional<Insurance> optInsurance = Optional.ofNullable(insurance); 
Optional<String> name = optInsurance.map(Insurance::getName); 

上述代码得到一个Optional<String>对象,那么如何获取最终的String值,java8提供了如下几种方式:

  1. Optional.get()

最简单但又最不安全的方法。如果变量存在,它直接返回封装的变量 值,否则就抛出一个NoSuchElementException异常。

  1. Optional.orElseGet(Supplier<? extends T> other)

是orElse方法的延迟调用版,Supplier 方法只有在Optional对象不含值时才执行调用

  1. Optional.orElseThrow(Supplier<? extends X> exceptionSupplier)

和get方法非常类似, 它们遭遇Optional对象为空时都会抛出一个定制的异常

  1. Optional.orElse(T other)

允许你在 Optional对象不包含值时提供一个默认值。

  1. Optional.ifPresent(Consumer<? super T>)

让你能在变量值存在时执行一个作为参数传入的 方法,否则就不进行任何操作

  • 使用flatMap连接Optional对象

    获取最终的name

    Optional<Person> optPerson = Optional.of(person);
    optPerson.flatMap(Person::getCar) 
                         .flatMap(Car::getInsurance)
                         .map(Insurance::getName)
                         .orElse("Unknown");
    

相关文章

网友评论

      本文标题:Optional

      本文链接:https://www.haomeiwen.com/subject/ewbjgftx.html