可选用于表示可为空的对象,此类的一些用法包括
对于第一种情况,我是否需要在所有可空的返回方法中返回Optional?
答案 0 :(得分:75)
那么可选的错误是什么?
我们面临的问题是:JDK 8可选对象是否会删除空引用?答案是强调不!因此,批评者立即质疑其价值问题:那么我们还不能通过其他方式做什么有益呢?
与SML或Haskell之类的函数式语言不同,它们从未有过空引用的概念,在Java中我们不能简单地去除历史上存在的空引用。这将继续存在,并且可以说它们具有正确的用途(仅举一例:three-valued logic)。
我怀疑Optional类的意图是替换每一个可以为空的引用,但是为了帮助创建更强大的API,只需通过读取方法的签名,我们可以告诉我们是否可以期望一个可选值与否,并强制程序员相应地使用此值。但最终,Optional将只是另一个引用,并且受到语言中每个其他引用的相同弱点(例如,您可以返回null可选)。很明显,Optional不会挽救这一天。
如何使用这些可选对象或者它们在Java中是否有价值一直是项目lambda邮件列表中heated debate的问题。从批评者那里我们听到了有趣的论点,如:
因此,看起来Optional的好处确实值得怀疑,并且可能仅限于提高可读性和执行公共接口合同。
我确实认为采用这种可选的功能习惯可能会使我们的代码更安全,更少提示无效解除引用问题,因此更加健壮且不易出错。当然,它不是一个完美的解决方案,因为,毕竟,可选引用也可能被错误地设置为空引用,但我希望程序员坚持不传递空引用的约定,其中可选对象是预期的,几乎就像我们今天认为一个好的做法是不要在需要集合或数组的地方传递空引用,在这些情况下,正确的方法是传递一个空数组或集合。这里的要点是,现在我们在API中有一个机制可以用来明确表示对于给定的引用,我们可能没有值来分配它,并且API强制用户验证它。
引用Google Guava's article关于可选对象的使用:
“除了给出null之外的可读性的增加 名称,Optional的最大优点是它的白痴证明。它 如果你想要你的话,强迫你积极思考缺席的情况 程序要编译,因为你必须积极打开 可选并解决该案例“。
所以,我想每个API设计师都可以选择使用Optional的目的。
Stephen Colebourne和Brian Goetz等一些有影响力的开发者最近发表了一些有关正确使用可选项的有趣文章。我特别发现以下内容很有用:
答案 1 :(得分:8)
作为观察,我认为在构建应用程序时必须考虑的一个最重要的方面是决定如何处理“空问题”。
在这方面,第一步是确定空值的可能“来源”。例如,项目中使用的数据库或外部库。下一步是“包含”问题,即包装有问题的代码(使用Optional),从而阻止在整个系统中传播null,其中毫无疑问的代码可能会触发NPE。
要回答你的问题,这取决于...大多数时候我会说这是不必要的,因为它创造了许多没有价值的工作(例如,我不会对在类中调用其他私有方法的方法使用可选项,或者调用包私有类方法的方法,但是应用程序中不同“关注点”(或层)的瘦边界存在的代码,(接口/类的签名)例如,您用于查询数据存储区,或用于“传输”可能具有空属性的数据的pojos - DTO,或更一般的描述,已发布的不同模块的API)应该避免'泄漏'对其他一些有不同顾虑的领域是空的。
答案 2 :(得分:7)
与番石榴相比,java.util.Optional
的一个令人讨厌的问题是它没有提供像
orElse(Optional<T>): Optional<T>
在com.google.common.base.Optional
中定义为
or(Optional<T>): Optional<T>
缺少此特定功能限制了Java 8的可选的monadic应用程序。
<强>更新强>
可以像使用Java 8一样复制Guava的or(Optional<T>)
optionalA.map(Optional::of).orElse(optionalB)
或
optionalA.map(Optional::of).orElseGet(() -> computeOptionalB)
<强>更新强>
在Java 9(最后!),您将能够使用Optional.or(Supplier<Optional<T>>)
:
optionalA.or(() -> computeOptionalB)
那很整洁!