前言
Optional 是 Java8 引入的一个重要特性,它是一个容器,里面装着一个可能为空可能不为空的对象。在它出现之前,为避免空指针异常我们可能会这样编码:
1 | public String getLastFour(Employee employee) { |
显然代码嵌套层次很深不够整洁。而用 Optional 将值包裹起来后,我们可以不再关注于值会不会为 null
,会不会抛空指针,而将注意力集中在对数据的操作。并且 Optional 提供了 map
、flatMap
、filter
等方法让我们可以进行函数式风格的编码。那么上诉代码可以如此改写:
1 | public String getLastFour(Optional<Employee> employee) { |
更确切的说,Optional 是一个 Monad 容器。那什么是 Monad 呢?可以参考下面这段话: Think of monads as an object that wraps a value and allows us to apply a set of transformations on that value and get it back out with all the transformations applied.
简单的说,Monad 是一个包裹了一个值的容器(值可以是单个对象也可以是集合),允许我们对该值进行一系列的转换(函数操作)后返回给m我们期望的值。也就是说,Monad 封装了接收函数作为入参的一些方法(filter、map、flatMap 等)。
那么现在,让我们从源码开始一步一步揭开它的神秘面纱。
工厂方法
Optional 使用私有化的构造函数和单例模式提供了值为空的单例,暴露的静态工厂方法为 Optional.empty()
。该种设计感觉和 Java 设计模式中的空对象模式有异曲同工之妙,也是避免空指针的核心所在,后面我们将会提到。
1 | /** |