前言

之前遇到过使用Optional之后带来的隐含bug,现在强调记录一下不好的用法,防止错用。

Optional不能序列化,不能作为类的字段(field)

这点尤为重要,即类要纯粹。如果是POJO就原始类型就可以了,如果是领域对象,则更不应该使用Optional作为field。

Optional不适合作为方法参数

另一种不太适合使用Optional的情况是将该类型作为方法或者构造函数的参数,这将导致不必要的代码复杂化。

User user = new User("john@gmail.com", "1234", Optional.empty());

而且,内部如果忘记isPresent,会得到NoSuchElementException。所以

相反,使用方法重载(method overloading)来处理非强制性参数要方便得多。

推荐Optional作为函数返回值

使用Optional作为返回值可以增强stream处理,构建流式API. 比如, findFirst()就是返回一个Optional对象。

@Test
public void whenEmptyStream_thenReturnDefaultOptional() {
List<User> users = new ArrayList<>();
User user = users.stream().findFirst().orElse(new User("default", "1234")); assertEquals(user.getEmail(), "default");
}

Optional和steam组合更有益处

级联调用是危险的,很容易产生空指针。比如

String isocode = user.getAddress().getCountry().getIsocode().toUpperCase();

在传统做法里,

if (user != null) {
Address address = user.getAddress();
if (address != null) {
Country country = address.getCountry();
if (country != null) {
String isocode = country.getIsocode();
if (isocode != null) {
isocode = isocode.toUpperCase();
}
}
}
}

使用Optional可以精简代码,降低复杂度:

String result = Optional.ofNullable(user)
.flatMap(User::getAddress)
.flatMap(Address::getCountry)
.map(Country::getIsocode)
.orElse("default");

总结

Optional类对我们最有帮助的一个用例是同Stream或者其他方法组合使用,这些方法会返回一个可构建流畅API的Optional值。如果仅仅作为判空,那么不要使用Optional,直接判null就好。

比如,使用Stream 的Optional对象的例子:

@Test
public void whenGetStream_thenOk() {
User user = new User("john@gmail.com", "1234");
List<String> emails = Optional.ofNullable(user)
.stream()
.filter(u -> u.getEmail() != null && u.getEmail().contains("@"))
.map( u -> u.getEmail())
.collect(Collectors.toList()); assertTrue(emails.size() == 1);
assertEquals(emails.get(0), user.getEmail());
}

参考

原文链接:https://stackify.com/optional-java/

关于作者:

Eugen是一名软件工程师,对Spring、REST API、安全和教育拥有极大热情。同时,他还是Baeldung(推特账号@baeldung)的创始人。

Java中Optional使用注意事项的更多相关文章

  1. Java中Optional类的使用

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...

  2. java中Optional和Stream流的部分操作

    package test9; import java.util.DoubleSummaryStatistics; import java.util.Optional; import java.util ...

  3. java中的包注意事项

    1:需要导入包的三个地方 a:需要导入第三方的jar包中的类或接口 b:需要导入除了java.lang包的其他包中的类(jdk中的类) c:需要导入自己写的不同包的类 2:引入包的三种方式 a:imp ...

  4. java 中static关键字注意事项

    1.内存中存放的位置:(static修饰的方法和属性保存在方法区中,但是方法区也是堆的一部分) 内存的分区 2.什么样的属性可以定义为静态数据 例如: class person{ public Str ...

  5. java中数据类型转换注意事项

    1.byte.short.char这三种类型互相做数学运算时都会先提升为int类型后再做运算 char a = 'A'; short b = 1; int num = a + b;//a和b在做运算前 ...

  6. Java 中遇到null 和为空的情况,使用Optional来解决。

    Java 中遇到null 和为空的情况,使用Optional来解决 示例代码: package crazy; import java.util.Optional; class Company { pr ...

  7. map和flatmap的区别+理解、学习与使用 Java 中的 Optional

    转自:map和flatmap的区别 对于stream,   两者的输入都是stream的每一个元素,map的输出对应一个元素,必然是一个元素(null也是要返回),flatmap是0或者多个元素(为n ...

  8. java 中使用ajax调用后台方法注意事项

    java 中使用ajax调用后台方法注意事项,后台方法一定要加@ResponseBody jQuery.validator.addMethod("checkRuleName",fu ...

  9. JDK8 Java 中遇到null 和为空的情况,使用Optional来解决。

    空指针是我们最常见也最讨厌的异常,写过 Java 程序的同学,一般都遇到过 NullPointerException :) 初识null 详细可以参考[jdk 1.6 Java.lang.Null.P ...

随机推荐

  1. 【docker 一】入门实践、环境部署、基本操作指令、镜像库、数据卷

    简述 `docker是如火如荼的容器技术,今后会陆续上传关于微服务技术的学习笔记,希望能和大家一起学习一起分享!` docker环境搭建 1.获取最新版的Docker安装包 $ wget -qO- h ...

  2. ML—高斯判别分析

    华电北风吹 天津大学认知计算与应用重点实验室 日期:2015/12/11 高斯判别分析属于生成模型,模型终于学习一个特征-类别的联合概率. 0 多维正态分布 确定一个多维正态分布仅仅须要知道分布的均值 ...

  3. LeetCode90:Subsets II

    Given a collection of integers that might contain duplicates, nums, return all possible subsets. Not ...

  4. C语言之——文件操作模式

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47450667 "rt" 仅仅读打开一个文本文件.仅仅同意读数据 ...

  5. 九种迹象表明你该用Linux了

    实际上.你每天都或多或少的不知不觉地在使用Linux系统. 在webserver领域中,Linux是占主导地位的操作系统.包含你如今正在浏览的页面的后台,都是跑在Linux上的.甚至你整天不离手的An ...

  6. USACO Section 2.1 Healthy Holsteins

    /* ID: lucien23 PROG: holstein LANG: C++ */ #include <iostream> #include <fstream> #incl ...

  7. Memcached的安装与简单使用

    Memcached下载 如果是Win10系统,还需要单独安装telnet服务,因为Win10把它给阉掉了.(默认下一步下一步安装) 一.安装Memcached 将Memcached解压到目录,以管理员 ...

  8. JavaSe:UncaughtExceptionHandler

    Java中,出现对于异常的处理,通常是使用try{}catch()来捕获处理的.但是在使用trycatch时,未必会将所有的异常都捕获到,所以方法声明时可以有throws xxxException. ...

  9. redis主从配置+哨兵模式

    1.搭建redis主从,一个master两个slave,加一个哨兵监听(sentinel),可以新建三个虚拟机,模拟环境,我的电脑没那么多虚拟机,就在一台虚拟机上弄的. 2.安装redis,如果是三台 ...

  10. 《调试九法——软硬件错误的排查之道》【PDF】下载

    <调试九法--软硬件错误的排查之道>[PDF]下载链接: https://u253469.ctfile.com/fs/253469-231196352 内容简介 <调试九法:软硬件错 ...