XXX
在我上一篇文章中,我提倡在所有使用 null 的地方都用 Optional 来替代。
事实证明,我与 Optional 的专家产生了分歧。这让我很疑惑,因此我决定阅读 Optional 引入的原因,并在这篇文章分享我的发现。
这篇文章主要总结 Optional 在 Java 8 中的引入过程。在此过程中,尽可能引用作者的原话。我希望能正确表述我的观点,但是由于讨论很频繁且冗长,有的时候还引起热议,这并不是件简单的事。文章结尾,我会把作者的观点和我的观点进行对比。
JSR 335
Java 语言规范第 335 条用于处理 Java 中的 Lambda 表达式,它的目的在于:
Extend the Java language to support compact lambda expressions (closures), as well as related language and library features to enable the Java SE APIs to use lambda expressions effectively.
这是 Java 8 引入 Optional 的前提条件。
JSR-335 的专家组成员讨论 Optional 也非常积极,包括 Brian Goetz,Doug Lea and Rémi Forax。还有众所周知的专家 Joshua Bloch,Tim Peierls 等。
该文章的数据是从 lambda-libs-spec-experts的历史邮件中来的,你可以在这里查看,我加了一些样式美化。
Optional 详解
首次提及
最先提到 Optional 的应该是 Rémi Forax,尽管是 Doug Lea 写的邮件。在这封邮件中,他简要概述了 Optional 的理由。
这些年来,关于
Optional的讨论层出不穷。我认为主要涉及到两个技术问题,外加一个使用风格的问题:
一些集合类允许保存 null 元素,但这并不意味能随意地在集合类中使用 null,用来表示
元素不存在的情况除外。API 在扩展的时候可能会影响到原来的流程。例如:在方法没有返回值的时候不会 return,但 Optional 的替代方法是返回一个装箱类型,大多数人都不愿意去做。
大多数人喜欢使用 Optional 的链式API,使编码更流畅。像这样:
x = s.findFirst().or(valueIfEmpty) vs if (( x = s.findFirst()) == null ) x = valueIfEmpty 为了做到这一点,大部分人都乐于创建一个 Optional。但是当它传递到其他地方时,就会让人头疼了,像
Set<Option<T>>。这些很难具有说服力。 Doug Lea - Sep 14 2012
顺便说下:XXXX
在关于 Stream 文章中讨论到:Optional 仅被描述为集合查询的返回类型。更进一步说,他是用于 Stream 的终止操作。如果 Stream 是空的,则它的终止操作就不能返回值。( Stream 的不返回值得终止操作目前有 reduce、min、max、findFirst 和 findAny)
这个结论印证了已经持有的观点:使用 Optional 作为返回值的类型。
