Java中Optional使用注意事项

前言

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

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

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

Optional不能作为方法参数

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

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

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

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)的创始人。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

第五节:Go语言常量

干货来了!!!为了让更多的小伙伴喜欢Golang、加入Golang之中来,Golang语言社区发起人彬哥联合业界大牛共同推出了Go语言基础、进阶、提高课程,目前...

1092
来自专栏PPV课数据科学社区

零基础到精通Python,从这篇文章开始

关键词:Python,入门 正文: 本文由rever4433, Tocy, Tony, 南宫冰郁, 透过树叶的光等协作翻译,发表于开源中国。 什么是 Pytho...

2996
来自专栏程序员宝库

关于 Java 你不知道的 10 件事

作为 Java 书呆子,比起实用技能,我们会对介绍 Java 和 JVM 的概念细节更感兴趣。因此我想推荐 Lukas Eder 在 jooq.org 发表的原...

3826
来自专栏专知

【Leetcode 303】关关的刷题日记67–Leetcode 303 Range Sum Query – Immutable

关关的刷题日记67 – Leetcode 303 Range Sum Query – Immutable 题目 Given an integer array n...

3098
来自专栏小詹同学

【记录帖】(No.002)从零打卡刷Leetcode

小詹一直觉得自己编程能力不强,想在网上刷题,又怕不能坚持。不知道有木有和小伙伴和小詹一样想找个人一起刷题呢?欢迎和小詹一起定期刷leetcode,每周一周五更新...

1404
来自专栏函数式编程语言及工具

泛函编程(0)-什么是泛函编程

 什么是泛函编程(Functional Programming)?泛函编程就是用函数编写程序。这个回答太抽象,等于没说。 再说清楚一点:泛函编程就想砌积木一样把...

2128
来自专栏程序员宝库

关于 Java 你不知道的 10 件事

作为 Java 书呆子,比起实用技能,我们会对介绍 Java 和 JVM 的概念细节更感兴趣。因此我想推荐 Lukas Eder 在 jooq.org 发表的原...

3075
来自专栏好好学java的技术栈

轻松看懂java设计模式简单工厂模式

简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

1812
来自专栏一个会写诗的程序员的博客

《Kotlin 程序设计》第五章 Kotlin 面向对象编程(OOP)第五章 Kotlin 面向对象编程(OOP)1. 面向对象的HelloWorld 2. 面向对象编程思想简述3.Kotlin 面向

Kotlin 同Java、 Scala、Groovy 一样,都使用关键字class 来定义类。

1433
来自专栏Petrichor的专栏

什么是:语法糖、语法盐、语法糖精

4765

扫码关注云+社区

领取腾讯云代金券