Java Optional是如何随时间演变的

如果你对特定特性何时被引入可选API感兴趣。在这里你可以找到它从Java 8到现在的演变的描述。

Why Does OJava中甚至有选项?

这里,原因很简单。在许多现代编程语言中,有一个特性(或者一个bug,取决于你怎么想)叫做“十亿美元的错误或者空指针引用。对于Java,它允许NullPointerException发生。

NPE是最常见的运行时异常之一。它往往会出现在我们代码库中最意想不到和最不想要的地方,给我们和我们的客户带来很多麻烦。在Java 8之前,处理它们的唯一方法是使用“if ladder”,负责检查对象是否不为空,这会使我们的代码看起来像下面的示例。

​private String getAssignManagerName(Task task) {
    if (task != null) {
        Team team = task.getAssignTeam();
        if (team != null) {
            Manager manager = team.getManager();
            if (manager != null) {
                return manager.getName();
            }
        }
    }
11
    throw new UnableToGetManagerNameException("Unable to get assign manager name");
12
}

如您所见,这段代码相当复杂和冗长。它必须在一个单独的语句中显式地进行每个非空检查,这就是为什么它最后有很多样板文件的原因。这个问题是Java引入Optional的主要原因之一。为了向您展示Optional的基本特性,我使用Java 8版本的类编写了一段代码,其含义与上面的代码相同。

​private String getAssignUserFirstName(Task task) {
    return Optional.ofNullable(task)
            .map(Task::getAssignTeam)
            .map(Team::getManager)
            .map(Manager::getName)
            .orElseThrow(() -> new UnableToGetManagerNameException("Unable to get assign manager name"));
}

正如您在这里看到的,几乎所有的事情都为我们做好了。首先,我们用可选的。然后,我们执行一系列地图对它进行操作。最后,如果我们的可选的是空的,或者我们不能在某一点上得到值,我们抛出一个异常orElseThrow.

我让你来决定哪一个对你来说更具可读性和更有意义,但对我来说答案是显而易见的。

介绍完毕。

从可选到Java版本的演变

在前一段中,我介绍了可选的一些基本特性。下面是Java 8和更高版本中提供的更多特性的描述。

Java 8

其他有用的方法包括:

  • of(T value),这类似于ofNullable(T value)但是应该只在您希望从非空值创建可选值时使用。
  • flatMap(Function<? super T,Optional<U>> mapper)
  • filter(Predicate<? super T> predicate)

如果value出现在我们的可选实例中,那么它们的工作方式与它们在Stream interface中的工作方式相同。

  • ifPresent(Consumer<? super T> consumer)

它接受消费者接口,并在可选值出现时调用它,否则它什么也不做。

  • orElseThrow(Supplier<? extends X> exceptionSupplier)

它接受供应商接口,如果该值不存在,它抛出一个由供应商创建的异常。

我故意没有描述Java 8 Optional中的所有方法,因为本文主要关注的是后续版本中添加的内容,而不是它在开始时的样子。如果您希望更熟悉所有方法,请查看Oracle官方文档.

Java 9

这是我们旅程的第一站。

该版本为我们的API带来了数量最多的新方法,即:

  • ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)

这里的定义非常简单,如果值存在,它将对它应用一个消费者动作,否则它执行一个提供的runnable动作。

  • or(Supplier<? extends Optional<? extends T>> supplier)

如果该值不存在,该方法将返回由供应商函数提供的可选值。

  • stream()

这里的定义也很明显。如果我们的值存在,它会将我们的可选值转换成包含该值的流。如果没有,我们得到空流。这种转换使我们能够访问Stream API中声明的所有方法,它比可选的API更强大,提供了更多的功能。

Java 10

不幸的是,在这个版本中,Oracle决定只给可选类添加一个新方法。一方面,它似乎很有用,但另一方面,却没那么有用。我将描述它,并让您来评价它的有用性。

  • orElseThrow()

H在这里,这将引发的异常n为我们定义了因此我们有不必须指定它。如果我们决定引起这种方法对空、O可选we将得到NoSuchElementException.

Java 11

最新的Java LTS版本是我们的下一站。

这里,我们又一次只有一个新方法。在我看来,这不是很有用。

它有以下签名isEmpty()与此相反我在场()自Java 8以来就存在的方法。准确地说,如果value不在我们的可选实例中,它将返回True。

Java 12及以上版本

不幸的是,自Java 11以来,可选API没有任何更新。我们将不得不等待Java 18版本发布内容计划,因为据我所知,在Java 18中没有为这个API计划进一步的变化。如果出现这样的变化,本文将会更新。

总结

我简要描述了一个最流行的Java类是如何随着时间的推移而改变以达到其当前状态的。通过3个Java LTS版本,我们得到了6个新方法,到目前为止,大约。可选类中所有方法的25%。有了它们,我们有了新的特性和可能的用例。我希望这篇文章能让您更好地理解可选API是如何随着后续Java版本而变化的,以及为什么使用Java 9或11比使用Java 8更好。

最后

感谢阅读,更多的java课程学习路线,笔记,面试等架构资料,点赞收藏+评论转发+关注我之后私信我【学习】即可获取更多免费资料!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值