java8学习之Optional深入详解

自上次【http://www.cnblogs.com/webor2006/p/8243874.html】函数式接口的学习告一段落之后,这次来学习一下Optional,它并非是函数式接口的概念,点击查看源码便知:

java8学习之Optional深入详解

那它是用来干嘛的呢?其实用它是用来避勉非常常见的NPE(NullPointerException),我想对于java程序猿来说它是再亲切不过的了,往往项目上线之后由于它的存在可能会导致紧急上修复包把自己整得够呛,既然空指针异常在实际项目中是大量存在的,所以说现在有很多编程语言对空指针异常做了一定程序的规避,而规避的办法都是采用这次要学的Optional方式,所以说学习它还是很有意义的。

了解它从javadoc开始:

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

接着来查看一下什么叫"value-based" Classes,可以从J2SE文档点击链接查看说明:

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

 java8学习之Optional深入详解

根据官网的解释,那再回过头来看一下咱们学习的Optional:

java8学习之Optional深入详解

既然它的构造方法是私有的,那如何构造它呢?提供了三个工厂方法来创建它:

java8学习之Optional深入详解

下面一一看一下:

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

接下来再来看一下这两个方法:

java8学习之Optional深入详解

好了,初步对Optional的这些方法有了了解之后,接下来使用一下它,光说不练假把式:

java8学习之Optional深入详解

那如果把这个isPresent()判断去掉呢?

java8学习之Optional深入详解

但是!!Optional的标准使用在拿值时一定用isPresent()方法来判断是否有值,如果缺少它的判断就直接去拿值可能会有空指针的问题。

那思考一下目前使用了Optional之后跟之前传统的使用有啥不同,下面对比下:

java8学习之Optional深入详解

既然本质没啥区别,那干嘛要使用Optional呢?其实目前Optional的写法还是用的传统面向对象的写法,而它推荐的写法不是这样的,那是怎样的呢?看一下IDE的提示:

java8学习之Optional深入详解

鼠标放在上面既可以看到提示:

java8学习之Optional深入详解

那推荐的这种函数式的编程风格长啥样呢?继续可以使用智能ide的提示来修改,如下:

java8学习之Optional深入详解

编译运行:

java8学习之Optional深入详解

这才是Optional使用的一个推荐的方式,那optional.ifPresent()方法是怎么定义的呢?看下源码:

java8学习之Optional深入详解

既然不担心空指针的问题,那下面来验证下我们构造一个null的Optional对象,然后看是否会报空指针:

java8学习之Optional深入详解

另外Optional还有其它的一个有用的方法,比如说如果发现值为null则打印一个默认的值,具体怎么做呢,如下:

java8学习之Optional深入详解

看一下它的具体实现:

java8学习之Optional深入详解

接着继续使用Optional的其它方法:

java8学习之Optional深入详解

那看一下它的方法定义:

java8学习之Optional深入详解

所以咱们定义一个有值的Optional验证一下:

java8学习之Optional深入详解

另外对于Optional还有另外一个择中的方法ofNullable(),也就是既可以有值也可以没值,如下:

java8学习之Optional深入详解

关于这三个工厂方法:empty()、of()、ofNullable(),具体要怎么选择呢?如果实际发现数据一定是null则可以有empty(),而如果一定不是null则可以选用of(),如果不能确定该数据是空还不是空则可以用ofNullable(),具体场景具体选择。

接下来再来举另外一个例子,对于一个方法如果返回一个集合,当集合数据为空的时候这时好的写法就是不要直接加为null,而是要返回一个空的集合,这样对于调用方而言就不会对集合数据进行判空了,所以以它为例再来看一下使用Optional的好处,首先建两个实体,这两个实体是一对多的关系,如下:

java8学习之Optional深入详解

java8学习之Optional深入详解

接着实例化一些数据,如下:

java8学习之Optional深入详解

接着再从company中取出所有的员工,有可能为空也有可能不为空,按传递的写法可能是这样写,伪码如下:

java8学习之Optional深入详解

那接下来用Optional如何用更简单的方式来达到上面同样的效果:

java8学习之Optional深入详解

其中map()方法看一下它的定义:

java8学习之Optional深入详解

接下来编译运行:

java8学习之Optional深入详解

接下来将公司的员工信息去掉,再来看打印:

java8学习之Optional深入详解

可见用Optional处理这块的逻辑完全是函数式风格的,看着也比较舒服。

另外还有一个细节需要注意,如果将Optional做为一个方法的参数,如下:

java8学习之Optional深入详解

然后看一下具体是啥警告:

java8学习之Optional深入详解

接着继续读一下原因:

java8学习之Optional深入详解

java8学习之Optional深入详解

java8学习之Optional深入详解

再看一下Optional类,确实是木有实现序列化接口:

java8学习之Optional深入详解

所以这里需要强调:不要将Optional作为方法参数进行定义,也不要在类中声明Optional类型的变量,Optional通常只做为方法的返回值来规避空指针问题。