Optional

背景

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 本章内容 如何为缺失的值建模 Optional 类 应用Optional的几种模式 使用Opti...
    追憶逝水年華阅读 1,814评论 0 0
  • 关于java8 Optional 文档版本:v1.0版本 和C/C++不一样,java从一开始就尝试将指针彻底的包...
    比轩阅读 3,794评论 1 22
  • Optional的学习与实战 整片文章大部分内容来自java8实战这本书,我在这里也是将自己的学习过程记录下来,并...
    Java大宝宝阅读 2,934评论 2 0
  • 由于Optional未能实现Serializable接口,若使用了某些要求序列化的库或者框架,在域模型中使用Opt...
    PawsUp阅读 778评论 0 0
  • 1. 简介 本文简要介绍一下Java 8 引入的 Optional 类。引入Optional 类的主要目的是为使用...
    大哥你先走阅读 3,614评论 1 58