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() ...
随机推荐
- 18_andriod常用布局&内容回顾
线性布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:androi ...
- 面试题: mysql数据库 已看1 简单的sql练习
数据库总结--MySQL常见面试题 2015年03月24日 17:56:06 阅读数:7787 1.根据部门号从高到低,工资从低到高列出员工的信息 select * from employee ord ...
- [转发]深入理解git,从研究git目录开始
转发学习的啦. 似乎很少有人在读某个git快速教程的时候会说:“这个关于git的快速教程太酷了!读完了用起git来超级舒服,并且我一点也不怕自己会破坏什么东西.” 对git的初学者来说,刚接触git时 ...
- 简单Hadoop集群环境搭建
最近大数据课程需要我们熟悉分布式环境,每组分配了四台服务器,正好熟悉一下hadoop相关的操作. 注:以下带有(master)字样为只需在master机器进行,(ALL)则表示需要在所有master和 ...
- How to install Samba server on Ubuntu 12.04
Part 1: Configuring anonymous share with samba server To install the samba package,enter the followi ...
- 关于.net Core项目发布在Linux上的填坑
本文主要记录.net Core项目发布在Linux服务器上面所遇到的问题,防止遗忘是 1.在发布文件中执行 dotnet xxxxxx.dll的时候提示如下错误: An assembly specif ...
- sql server 中raiserror的使用
server数据库中raiserror的作用就和asp.net中的throw new Exception一样,用于抛出一个异常或错误.这个错误可以被程序捕捉到. raiserror('错误的描述',错 ...
- 反射实现增删改查(DAO层)——修改数据
先贴出代码,后续补充自己的思路.配置文件.使用方式: /** * * 修改数据 * */ @Override public void updateObject(Object object, Strin ...
- go语言web开发框架_Iris框架讲解(六):Session的使用和控制
在实际的项目开发中,我们会经常有业务场景使用到Session功能.在iris框架中,也为我们提供了方便使用,功能齐全的Session模块.Session模块的源码目录为kataras/iris/ses ...
- cf835(预处理 + 记忆化dp)
题目链接: http://codeforces.com/contest/835/problem/D 题意: 定义 k 度回文串为左半部分和右半部分为 k - 1 度的回文串 . 给出一个字符串 s, ...