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

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






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









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

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

下面一一看一下:



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

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

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

但是!!Optional的标准使用在拿值时一定用isPresent()方法来判断是否有值,如果缺少它的判断就直接去拿值可能会有空指针的问题。
那思考一下目前使用了Optional之后跟之前传统的使用有啥不同,下面对比下:

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

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

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

编译运行:

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

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

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

看一下它的具体实现:

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

那看一下它的方法定义:

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

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

关于这三个工厂方法:empty()、of()、ofNullable(),具体要怎么选择呢?如果实际发现数据一定是null则可以有empty(),而如果一定不是null则可以选用of(),如果不能确定该数据是空还不是空则可以用ofNullable(),具体场景具体选择。
接下来再来举另外一个例子,对于一个方法如果返回一个集合,当集合数据为空的时候这时好的写法就是不要直接加为null,而是要返回一个空的集合,这样对于调用方而言就不会对集合数据进行判空了,所以以它为例再来看一下使用Optional的好处,首先建两个实体,这两个实体是一对多的关系,如下:


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

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

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

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

接下来编译运行:

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

可见用Optional处理这块的逻辑完全是函数式风格的,看着也比较舒服。
另外还有一个细节需要注意,如果将Optional做为一个方法的参数,如下:

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

接着继续读一下原因:



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

所以这里需要强调:不要将Optional作为方法参数进行定义,也不要在类中声明Optional类型的变量,Optional通常只做为方法的返回值来规避空指针问题。
java8学习之Optional深入详解的更多相关文章
- java8学习之方法引用详解及默认方法分析
方法引用: 之前花了很多时间对Lambda表达式进行了深入的学习,接下来开启新的主题---方法引用(Method References),其实在之前的学习中已经使用过了,如: 那方法引用跟Lambda ...
- Java基础学习总结(33)——Java8 十大新特性详解
Java8 十大新特性详解 本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API ...
- [深入学习Web安全](5)详解MySQL注射
[深入学习Web安全](5)详解MySQL注射 0x00 目录 0x00 目录 0x01 MySQL注射的简单介绍 0x02 对于information_schema库的研究 0x03 注射第一步—— ...
- Shell学习之Bash变量详解(二)
Shell学习之Bash变量详解 目录 Bash变量 Bash变量注意点 用户自定义变量 环境变量 位置参数变量 预定义变量 Bash变量 用户自定义变量:在Bash中由用户定义的变量. 环境变量:这 ...
- Asp.Net MVC学习总结之过滤器详解(转载)
来源:http://www.php.cn/csharp-article-359736.html 一.过滤器简介 1.1.理解什么是过滤器 1.过滤器(Filters)就是向请求处理管道中注入额外的 ...
- Linux学习之用户配置文件详解(十四)
Linux学习之用户配置文件详解 目录 用户信息文件/etc/password 影子文件/etc/shadow 组信息文件/etc/group 组密码文件/etc/gshadow 用户信息文件/etc ...
- [转载]springmvc学习之@ModelAttribute运用详解
spring学习之@ModelAttribute运用详解 链接
- expect学习笔记及实例详解【转】
1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示:1.1 首行加上/usr/bin/expect1.2 spawn: 后面加上需要执行的shell命令,比如说sp ...
- Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)
[Android布局学习系列] 1.Android 布局学习之——Layout(布局)详解一 2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数) 3.And ...
随机推荐
- 3.React中的setstate的几个现象
转载segfault 上面的一篇文章,https://segmentfault.com/a/1190000014498196 1.在同一个方法中多次setState是会被合并的,并且对相同属性的设置只 ...
- JAVA实验报告及第七周总结
JAVA第六周作业 实验报告五 第一题 1.设计一个类层次,定义一个抽象类--形状,其中包括有求形状的面积的抽象方法. 继承该抽象类定义三角型.矩形.圆. 分别创建一个三角形.矩形.圆存对象,将各类图 ...
- Daily Temperatures
Given a list of daily temperatures T, return a list such that, for each day in the input, tells you ...
- WijmoJS 中自定义 React 菜单和列表项模板
WijmoJS 中自定义 React 菜单和列表项模板 在V2019.0 Update2 的全新版本中,React 框架下 WijmoJS 的前端UI组件功能再度增强. WijmoJS的菜单和类似列表 ...
- 什么是负载均衡SLB
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务.负载均衡可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性. 请看视频简介 ...
- 写着玩的bash脚本
#!/bin/bash function strealingManu { pwdfolder=`pwd` for var in "$@" do man 1 $var > $p ...
- Laravel-admin 消息提醒、播放音频、点击跳转
jquery-toastr 消息提醒.播放音频.点击跳转 应用情景,有新的订单生成,后台进行消息提醒并播放音频(这里用到轮询简单实现):下面附代码 1.找到laravel-admin 中的 index ...
- redis 命令 setbit、bitcount、getbit、bitop
1.SETBIT key offset value 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit). 在redis中,存储的字符串都是以二级制的进行存在的. 举例: 设置一个 ke ...
- X86逆向12:内存补丁的制作
本章我们将学习各种打补丁的方式,补丁在软件的破解过程中非常的重要,比如软件无法脱壳我们就只能通过打补丁的方式来破解程序,补丁原理就是当程序运行起来会被释放到内存并解码,然后补丁就通过地址或特征码定位到 ...
- [C#]使用BackgroudWorker刷新UI延迟的解决方法
今天使用BackgroundWorker刷新UI发生延时现象,找了好久才发现AutoResetEvent可以解决,代码如下 private void BgWorker_ProgressChanged( ...