当前位置: 首页 > 知识库问答 >
问题:

我是否应该对每个可能返回NULL的方法使用Java8/Guava可选?

谷泳
2023-03-14

可选的用于表示可为空的对象,该类的一些用途包括

  1. 作为方法返回类型,作为返回null以
    表示没有可用值
  2. 的替代方法
  3. 区分“未知”(例如,不存在于映射中)和“已知无值”(存在于映射中,具有值
    optional.缺席())
  4. 将可为null的引用包装起来存储在不支持null的集合中(不过有几种其他方法应该首先考虑)

对于第一种情况,我是否需要在所有可为空的返回方法中返回可选的?

共有1个答案

谷飞星
2023-03-14

那可有可无有什么问题呢?

我们面临的问题是:JDK8可选对象是否会摆脱空引用?答案是肯定的否定!因此,诋毁者立即质疑它的价值:那我们用其他方法已经做不到的有什么好处呢?

与SML或Haskell等函数式语言不同,它们从来没有空引用的概念,在Java中,我们不能简单地去掉历史上存在的空引用。这将继续存在,它们可以说有其适当的用途(只提一个例子:三值逻辑)。

  • 存在其他替代方案的事实(例如,IntelliJ和Eclipse IDE等IDE支持一组专有注释,用于静态分析可为空性,JSR-305具有@nullable和@nonnull等注释)。
  • 有些人希望它能像在函数世界中一样使用,这在Java中是不完全可能的,因为该语言缺少SML或Haskell等函数编程语言中存在的许多特性(例如模式匹配)。
  • 其他人争论如何不可能修改现有代码来使用此习惯用法(例如,List.Get(对象),它将继续返回null)。
  • 和一些人抱怨这样一个事实,即缺少对可选值的语言支持,可能会在API中不一致地使用可选值,从而产生不兼容性,就像我们在Java API的其余部分中遇到的一样,这些部分不能进行修改以使用新的可选类。这基本上是你的问题。在Ceylon或Kotlin等支持可选类型的语言中,您甚至不会质疑这一点。
  • 一个令人信服的论点是,如果程序员在一个可选对象中调用get方法,如果它为空,它将引发一个NoSuchElementException,这与我们在Null中遇到的问题差不多,只是有一个不同的异常。

因此,看来可选的好处确实是有问题的,并且可能仅限于提高可读性和强制执行公共接口契约。

我相信,采用这种可选的函数习惯用法可能会使我们的代码更安全,不那么容易出现空引用问题,因此更健壮,更不容易出错。当然,这不是一个完美的解决方案,因为毕竟,可选引用也可能被错误地设置为空引用,但我希望程序员坚持在需要可选对象的地方不传递空引用的惯例,就像我们今天认为在需要集合或数组的地方不传递空引用的做法一样,在这些情况下,正确的做法是传递空数组或集合。这里的重点是,现在我们在API中有了一个机制,我们可以使用它来明确表示,对于给定的引用,我们可能没有一个值可以分配给它,并且API强制用户验证这一点。

引用Google Guava关于可选对象使用的文章:

“除了通过给null命名来增加可读性之外,Optional的最大优点是它的防白痴性。如果你想让你的程序编译的话,它会迫使你积极地考虑不存在的情况,因为你必须积极地打开可选的并处理那个情况“。

所以,我想应该由每个API设计者来选择他们想要在可选的使用上走多远。

一些有影响力的开发人员,比如Stephen Colebourne和Brian Goetz,最近发表了一些关于如何正确使用Optional的有趣文章。我特别发现以下方法有用:

    null
 类似资料:
  • 我在flock手册中找到以下描述: 默认情况下,此功能将一直阻止,直到获得请求的锁为止 在下面,我找到了以下示例代码: 但是,是否存在脚本实际返回“无法获取锁”的情况 ?我以为它会等到文件

  • 文件: Authentication authenticate(Authentication Authentication)抛出AuthenticationException使用与AuthenticationManager相同的约定执行身份验证。参数:authentication-身份验证请求对象。返回:包含凭据的经过完全身份验证的对象。如果AuthenticationProvider无法支持传递

  • 问题内容: 中引入的type对许多开发人员来说都是新事物。 用方法返回类型代替经典方法是一种好习惯吗?假设值可以是。 问题答案: 当然,人们会做他们想要的。但是添加此功能时我们确实有明确的意图,并且它并不是通用的Maybe类型,因为许多人希望我们这样做。我们的意图是为库方法返回类型提供一种有限的机制,其中需要一种明确的方法来表示“无结果”,并且使用这种方法极有可能导致错误。 例如,你可能永远不要将

  • 或者这样会更好: 附注。抱歉开始新的话题,但我的业力不允许我评论答案。

  • 我试图模拟一个对象,该对象返回一个带有Mockito的Java可选对象: 当被调用,它返回。 我希望方法返回 返回的任何原因? 方法如下: 以下是Junit: