原文出处: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的更多相关文章

  1. 乐字节-Java8新特性之Optional

    上一篇小乐带大家了解了Java新特性之Stream,接下来将会继续述说Java新特性之Optional Optional<T>类(java.util.Optional)是一个容器类,代表一 ...

  2. java8新特性之Optional类

    NullPointException可以说是所有java程序员都遇到过的一个异常,虽然java从设计之初就力图让程序员脱离指针的苦海,但是指针确实是实际存在的,而java设计者也只能是让指针在java ...

  3. 乐字节Java8核心特性之Optional类

    大家好啊,上次小乐给大家介绍了Java8最最重要的一个特性——Stream流,点击可以回顾哦. Optional<T>类(java.util.Optional)是一个容器类,代表一个值存在 ...

  4. Java8新特性之Optional

    空指针异常一直是困扰Java程序员的问题,也是我们必须要考虑的.当业务代码中充满了if else判断null 的时候程序变得不再优雅,在Java8中提供了Optional类为我们解决NullPoint ...

  5. 【Java8新特性】Optional类在处理空值判断场景的应用 回避空指针异常 编写健壮的应用程序

    一.序言 空值异常是应用运行时常见的异常,传统方式为了编写健壮的应用,常常使用多层嵌套逻辑判断回避空指针异常.Java8新特性之Optional为此类问题提供了优雅的解决方式. 广大程序员朋友对空值异 ...

  6. 【原创】JAVA8之妙用Optional解决NPE问题

    引言 在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException.假设我们有两个类,他们的UML类图如下图所示 在这种情况下,有如下代码 user. ...

  7. java8新特性六-Optional 类

    Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容器:它可以保存类型T的值,或者仅仅保 ...

  8. 夯实Java基础(二十四)——Java8新特征之Optional类

    1.概述 对于Java程序员来说,到目前为止出现次数最多的应该是NullpointException,它是导致Java应用程序失败的最常见原因.之前处理空指针我们必须先通过条件先去判断,然后再确认是否 ...

  9. Java8的新特性--Optional

    目录 Optional 一.Optional类是什么? 二.Optional类常用的方法 1. 创建Optional实例 1.1 Optional.of(T) 1.2 Optional.empty() ...

随机推荐

  1. Shape和 layer-list

    shape 基本使用 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android= ...

  2. Loadrunner 监控 Linux (centos6.5)服务器系统资源

    Loadrunner 监控 Linux 服务器系统资源,需要在被监控的服务器上启用 rstatd 进程但尝试启动时,爆炸了: [root@test1 rpc.rstatd-4.0.1]# rpc.rs ...

  3. Javax ws 01

    1 EndPoint发布服务 package com.gosaint.provider; import javax.jws.WebService; /** * @Authgor: gosaint * ...

  4. linux下将编译错误输出到一个文本文件

    linux下将编译错误输出到一个文本文件 command > filename 把把标准输出重定向到一个新文件中 command > > filename 把把标准输出重定向到一个文 ...

  5. qboimathtest1 t1 魔法串

    题目 小 N 最近在沉迷数学问题. 对于一个数字串 S,如果可以将它划分成两个数字 A.B,满足: 1. S=AB. 2. A.B 均不包含前导 0. 3. B 是 A 的倍数,且B / A是完全立方 ...

  6. 1.3 DVWA亲测sql注入漏洞

    LOW等级   我们先输入1 我们加上一个单引号,页面报错 我们看一下源代码: <?php if( isset( $_REQUEST[ 'Submit' ] ) ) { // Get input ...

  7. hdu1080

    #include<iostream> using namespace std; char s1[105],s2[105]; int val[5][5]={ {5,-1,-2,-1,-3}, ...

  8. 【Qt文档阅读】事件系统

    在Qt中,事件对象都继承于QEvent类,它表示应用程序内部或由于应用程序需要了解的外部活动而发生的事情.事件可以由QObject子类的任何实例接收和处理,尤其是widget.本文档描述如何在典型应用 ...

  9. 引用静态资源的url添加版本号,解决版本发布后的浏览器缓存有关问题

    在日常的工作中,我们经常会遇到页面文件(html,jsp等)中引用的js,css,图片等被修改后,而浏览器依然缓存着老版本的文件,客户一时半会看不到修改后的效果,同时也给生产环境的版本发布带来了一些问 ...

  10. Sharepoint2013商务智能学习笔记之Secure Store Service服务配置(二)

    Secure Store Service 是运行在应用程序服务器上的授权服务,它提供一个存储用户凭据的数据库,Secure Store Service 在商务智能中的地位很重要,Sharepoint商 ...