Java8 如何正确使用 Optional
原文出处:https://blog.kaaass.net/archives/764
Optional是Java8提供的为了解决null安全问题的一个API。善用Optional可以使我们代码中很多繁琐、丑陋的设计变得十分优雅。这篇文章是建立在你对Optional的用法有一定了解的基础上的,如果你还不太了解Optional,可以先去看看相关教程,或者查阅Java文档。
使用Optional,我们就可以把下面这样的代码进行改写。
1
2
3
4
5
|
public static String getName(User u) { if (u == null ) return "Unknown" ; return u.name; } |
不过,千万不要改写成这副样子。
1
2
3
4
5
6
|
public static String getName(User u) { Optional<User> user = Optional.ofNullable(u); if (!user.isPresent()) return "Unknown" ; return user.get().name; } |
这样改写非但不简洁,而且其操作还是和第一段代码一样。无非就是用isPresent方法来替代u==null。这样的改写并不是Optional正确的用法,我们再来改写一次。
1
2
3
4
5
|
public static String getName(User u) { return Optional.ofNullable(u) .map(user->user.name) .orElse( "Unknown" ); } |
这样才是正确使用Optional的姿势。那么按照这种思路,我们可以安心的进行链式调用,而不是一层层判断了。看一段代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
public static String getChampionName(Competition comp) throws IllegalArgumentException { if (comp != null ) { CompResult result = comp.getResult(); if (result != null ) { User champion = result.getChampion(); if (champion != null ) { return champion.getName(); } } } throw new IllegalArgumentException( "The value of param comp isn't available." ); } |
由于种种原因(比如:比赛还没有产生冠军、方法的非正常调用、某个方法的实现里埋藏的大礼包等等),我们并不能开心的一路comp.getResult().getChampion().getName()到底。而其他语言比如kotlin,就提供了在语法层面的操作符加持:comp?.getResult()?.getChampion()?.getName()。所以讲道理在Java里我们怎么办!
让我们看看经过Optional加持过后,这些代码会变成什么样子。
1
2
3
4
5
6
7
|
public static String getChampionName(Competition comp) throws IllegalArgumentException { return Optional.ofNullable(comp) .map(c->c.getResult()) .map(r->r.getChampion()) .map(u->u.getName()) .orElseThrow(()-> new IllegalArgumentException( "The value of param comp isn't available." )); } |
这就很舒服了。Optional给了我们一个真正优雅的Java风格的方法来解决null安全问题。虽然没有直接提供一个操作符写起来短,但是代码看起来依然很爽很舒服。更何况?.这样的语法好不好看还见仁见智呢。
还有很多不错的使用姿势,比如为空则不打印可以这么写:
1
|
string.ifPresent(System.out::println); |
Optional的魅力还不止于此,Optional还有一些神奇的用法,比如Optional可以用来检验参数的合法性。
1
2
3
4
|
public void setName(String name) throws IllegalArgumentException { this .name = Optional.ofNullable(name).filter(User::isNameValid) .orElseThrow(()-> new IllegalArgumentException( "Invalid username." )); } |
这样写参数合法性检测,应该足够优雅了吧。
Java8 如何正确使用 Optional的更多相关文章
- 乐字节-Java8新特性之Optional
上一篇小乐带大家了解了Java新特性之Stream,接下来将会继续述说Java新特性之Optional Optional<T>类(java.util.Optional)是一个容器类,代表一 ...
- java8新特性之Optional类
NullPointException可以说是所有java程序员都遇到过的一个异常,虽然java从设计之初就力图让程序员脱离指针的苦海,但是指针确实是实际存在的,而java设计者也只能是让指针在java ...
- 乐字节Java8核心特性之Optional类
大家好啊,上次小乐给大家介绍了Java8最最重要的一个特性——Stream流,点击可以回顾哦. Optional<T>类(java.util.Optional)是一个容器类,代表一个值存在 ...
- Java8新特性之Optional
空指针异常一直是困扰Java程序员的问题,也是我们必须要考虑的.当业务代码中充满了if else判断null 的时候程序变得不再优雅,在Java8中提供了Optional类为我们解决NullPoint ...
- 【Java8新特性】Optional类在处理空值判断场景的应用 回避空指针异常 编写健壮的应用程序
一.序言 空值异常是应用运行时常见的异常,传统方式为了编写健壮的应用,常常使用多层嵌套逻辑判断回避空指针异常.Java8新特性之Optional为此类问题提供了优雅的解决方式. 广大程序员朋友对空值异 ...
- 【原创】JAVA8之妙用Optional解决NPE问题
引言 在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException.假设我们有两个类,他们的UML类图如下图所示 在这种情况下,有如下代码 user. ...
- java8新特性六-Optional 类
Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容器:它可以保存类型T的值,或者仅仅保 ...
- 夯实Java基础(二十四)——Java8新特征之Optional类
1.概述 对于Java程序员来说,到目前为止出现次数最多的应该是NullpointException,它是导致Java应用程序失败的最常见原因.之前处理空指针我们必须先通过条件先去判断,然后再确认是否 ...
- Java8的新特性--Optional
目录 Optional 一.Optional类是什么? 二.Optional类常用的方法 1. 创建Optional实例 1.1 Optional.of(T) 1.2 Optional.empty() ...
随机推荐
- 利用java mail发送邮件
import java.util.Date; import java.util.Properties; import javax.activation.DataHandler; import java ...
- Spring 3.x 企业引用开发实战(陈雄华/林开雄)
目录 ... 第一章:Spring概述 IoC:BeanFactory.Context.El(SpringEL表达式) AOP:允许JVM虚拟机启动时使用代理类在运行时期修改指定类的字节码,改变一个类 ...
- Postman(调试工具)
Postman Postman用法简介-Http请求模拟工具 时间 2015-09-26 23:52:00 博客园-原创精华区 原文 http://www.cnblogs.com/codingbl ...
- SpringMVC RESTful中文乱码
开发中常遇到各种中文乱码很少心烦,这里总结了各种中文乱码https://www.cnblogs.com/lwx521/p/9856186.html 下面以SpringMVC遇到的中文乱码为例详解 首先 ...
- js验证文本框数字
输入框 <input name="title" type="text" oninput="onlyNum(this,'')" titl ...
- NIO和Reactor
本文参考Doug Lea的Scalable IO in Java. 网络服务 随着网络服务的越来越多,我们对网络服务的性能有了更高的要求,提供一个高性能,稳定的web服务是一件很麻烦的事情,所以有了n ...
- debian系Linux中文系统目录改为英文目录的解决方法
之前给笔记本装的kali是英文版,系统安装好了后再修改系统语言为中文,或者直接就用英文系统,也是可以的. 后来笔记本的硬盘坏掉了,换ssd,然后安装kali的中文版,中文是方便,但是进去后就不爽了. ...
- android build system resource links
总体结构,参见这里:http://www.jayway.com/2012/10/24/a-practical-approach-to-the-aosp-build-system/ 一般应用的Andro ...
- jq中打开新页面 并获取携带值
打开新页面:window.location.href = "./index.html?id=1"获取携带值: function GetRequest() { var url = l ...
- InnoDB信息说明
InnoDB是MySQL数据库发展至今一款至关重要的数据库存储引擎,其不仅支持事务特性,并且具有丰富的统计信息,便于数据库管理人员了解最近InnoDB存储引擎的运行状态. 早期版本的InnoDB存储引 ...