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 ...
随机推荐
- React Hook 学习
1.官方文档 https://react.docschina.org/docs/hooks-intro.html 2.阮一峰 reactHook http://www.ruanyifeng.com/b ...
- ValueError: numpy.dtype has the wrong size, try recompiling
问题ValueError: numpy.dtype has the wrong size, try recompiling解决 这是因为 Python 包的版本问题,例如安装了较旧版本的 Numpy, ...
- sql绕过转义符注入
宽字节绕过总结 1. 重点:转义符反斜杠\,ASCII码0x5C 2. 在双字节字符集中, 在\前面增加高字节,0x5C被当做低字节,组合为“汉字”,导致\符号被“吃掉”,后续字符逃出限制,从而绕 ...
- RestTemplateBuilder类
Spring Boot使用RestTemplate消费REST服务的几个问题记录 我们可以通过Spring Boot快速开发REST接口,同时也可能需要在实现接口的过程中,通过Spring Boot调 ...
- Excel小技巧(生成数字篇)
1. 自动生成1-1000: =ROW() 2.随机生成 1-100 : =RANDBETWEEN(1,100) // 若要包含小数点n位,就把(MIN,MAX)改成 (MIN*10^n,MAX*10 ...
- github与pycharm
再也不要使用命令行了 OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443
- mybatis-plus代码生成器两版(全部生成+部分生成)
mybatis-plus代码生成器两版(全部生成+部分生成) 一次性生成全部文件 package com.layuicms.erp.utils; import java.util.List; impo ...
- charindex函数的用法
例一: CustomName包含客户的First Name和Last Name,它们之间被一个空格隔开.我们用CHARINDX函数确定两个名字中间空格的位置.通过这个方法,我们可以分析ContactN ...
- ccpc湘潭邀请赛 Partial Sum
选定最多m的区间,使区间和的绝对值最大.但是左右端点不能重复选取 首先涉及到区间和的问题,就应该想到用前缀和去优化 这里对前缀和排序 然后贪心的去选取最大.次大 (比赛的时候脑子堵的很,没想出来 可惜 ...
- Flask:上下文管理
1. werkzurg from werkzur.serving import run_simple def run(environ,start_response): reuturn [b'hello ...