Optional

Null 带来的问题:

  • 它是错误之源
    NullPointerException是目前java程序开发中最典型的异常
  • 它会使代码膨胀
    它让你的代码充斥着深度嵌套的null检查,代码的可读性差
  • 它自身没有任何的语义
    尤其是,它代表了在静态类型语言中一种错误的方式对缺失的变量值的建模

    Optional类

    java8中引人了一个新的类java.util.Optional< T >。
    代码示例 1:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Person{
    private Optional < Car > car;
    public Optional< Car> getCar(){return car;}
    }
    public class Car{
    private Optional< Insurance> insurance;
    public Optional< Insurance> getInsurance(){return insurance;}
    }
    pubic class Insurance{
    private String name;
    pulic String getName(){return name;}
    }

当变量存在的时候,Optional类只是对类的简单封装。变量不存在的时候,缺失的值会被建模成为一个”空”的Optional对象,该对象可以由方法Optional.empty()返回,同时解引用这个Optional类的有效的”空”对象是完全不会出事的。

上述的代码示例中:

  • Person类表示某个人(实例)可能有车,也可能没车,因此将这个字段声明为Optional,表明Person是允许缺失的,通过Optional为缺失null安全建模;
  • Car类表示某台车可能买了保险,也有可能没有买保险;
  • Insurance类中,每个保险是肯定有名字的,所以无须声明为Optional;

使用Optional

  1. 创建一个Optional对象

    声明一个空的Optional:通过静态工厂方法Optional.empty(),创建一个空的Optional对象;
    Optional optCar = Optional.empty();
    或者,使用静态工厂方法Optional.ofNullable,创建一个允许null值得Optional对象
    Optional optCar = Optional.ofNullable(car);

  2. 利用map,flatmap从Optional对象中提取值
    参考java8中java.util.Optional函数Api可以得知map,flatmap的用法以及区别。借助上述的代码示例1,比较map方法与flatmap方法的用法。
    Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
    Optional<String> name = optInsurance.map(Insurance :: getName);
    这里的map用方法和流中的map用法几乎一致,map操作会将提供的函数应用于流的每个元素,这里我们将Optional对象看作一种特殊的集合,至少包含一个元素。如果Optional包含一个值,那函数就将改值作为参数传递给map,最后对将得到的值用Optional类包装。如果Optional为空,那就什么都不做。
    但是注意以下代码:
    Optional<Person> optPerson = Optional.of(person);
    这里optPerson是Optional类型的变量,调用map方法没有问题,但是其中包含的Person.getCar返回的是一个Optional类型的对象,导致optPerson.map(Person :: getCar);的结果是返回一个Optional>类型的变量。这个时候我们需要用到flatmap方法,可以将多层Optional包裹的值合并为一个Optional返回函数结果。

注意:Optional类并没有实现Serializable接口

0%