Edw*_*rzo 75
那么可选的错误是什么?
我们面临的问题是:JDK 8可选对象将摆脱空引用吗?答案是强调不!因此,批评者立即质疑其价值问题:那么我们还不能通过其他方式做什么有益呢?
与SML或Haskell等从未具有空引用概念的函数式语言不同,在Java中,我们不能简单地去除历史上存在的空引用.这将继续存在,他们可以说它们有适当的用途(仅举一个例子:三值逻辑).
I doubt that the intention with the Optional class is to replace every single nullable reference, but to help in the creation of more robust APIs in which just by reading the signature of a method we could tell if we can expect an optional value or not and force the programmer to use this value accordingly. But ultimately, Optional will be just another reference and subject to the same weaknesses of every other reference in the language (e.g. you could return a null Optional). It is quite evident that Optional is not going to save the day.
How these optional objects are supposed to be used or whether they are valuable or not in Java has been the matter of a heated debate in the project lambda mailing list. From the detractors we hear interesting arguments like:
因此,看起来Optional的好处确实值得怀疑,并且可能仅限于提高可读性和执行公共接口合同.
I do believe that the adoption of this Optional functional idiom is likely to make our code safer, less prompt to null dereferencing problems and as a result more robust and less error prone. Of course, it is not a perfect solution because, after all, Optional references can also be erroneously set to null references, but I would expect that programmers stick to the convention of not passing null references where an optional object is expected, pretty much as we today consider a good practice not to pass a null reference where a collection or an array is expected, in these cases the correct is to pass an empty array or collection. The point here is that now we have a mechanism in the API that we can use to make explicit that for a given reference we may not have a value to assign it and the user is forced, by the API, to verify that.
引用Google Guava关于可选对象使用的文章:
"除了通过赋予null名称而增加可读性之外,Optional的最大优势在于它的白痴证明.如果您希望程序完全编译,它会强制您主动考虑缺席案例,因为您必须主动解包可选并解决该案例".
所以,我想每个API设计师都可以选择他们想要使用Optional的目标.
像Stephen Colebourne和Brian Goetz这样的一些有影响力的开发者最近发表了一些有关正确使用可选项的有趣文章.我特别发现以下内容很有用:
作为观察,我认为在构建应用程序时必须考虑的最重要方面之一是决定如何处理"空问题".在这方面,第一步是确定空值的可能"来源".例如,项目中使用的数据库或外部库.下一步是"包含"问题,即包装有问题的代码(使用Optional),从而阻止在整个系统中传播null,其中毫无疑问的代码可能会触发NPE.
要回答你的问题,这取决于...大多数时候我会说这是不必要的,因为它创造了许多没有价值的工作(例如,我不会对在类中调用其他私有方法的方法使用可选项,或者调用包私有类方法的方法,但是存在于应用程序中不同"关注点"(或层)的细微边界的代码,(用于查询数据存储区的接口/类的签名,例如,或者用于"传输"可能具有空属性的数据的pojos - 或者,更一般的描述,不同模块的已发布的 API)应避免将空值"泄漏"到具有不同关注点的其他区域.
与番石榴相比,一个令人烦恼的问题java.util.Optional是它没有提供类似的方法
orElse(Optional<T>): Optional<T>
另一方面,它定义com.google.common.base.Optional为
or(Optional<T>): Optional<T>
缺少此特定功能限制了Java 8的Optional的monadic应用程序.
更新:
or(Optional<T>)可以像使用Java 8 Optional as一样复制Guava
optionalA.map(Optional::of).orElse(optionalB)
要么
optionalA.map(Optional::of).orElseGet(() -> computeOptionalB)
更新:
在Java 9中(最后!),您将能够使用Optional.or(Supplier<Optional<T>>):
optionalA.or(() -> computeOptionalB)
那很整齐!