【问题标题】:Guava Optional as method argument for optional parametersGuava Optional 作为可选参数的方法参数
【发布时间】:2014-08-05 07:17:16
【问题描述】:

最近我和我的队友讨论了在方法中使用GuavaOptional作为可选参数。

假设方法是

List<Book> getBooks(String catalogId, Optional<String> categoryId) {
     Validate.notNull(catalogId);
     Validate.notNull(categoryId); // Point of conflict. Is this required?

它接受一个catalogId 和一个可选 categoryId,它返回该目录中列出的书籍,如果类别也被传递,则仅返回该类别中的书籍。

冲突点是,验证 Optional&lt;String&gt; categoryId 以进行空检查。我认为不应该对其进行空检查,因为它是一个可选参数。函数的调用者可以传递nullOptional.&lt;String&gt;absent()getBooks 函数应该通过在实现中执行if(categoryId==null &amp;&amp; categoryId.isPresent()) 来处理这两种情况。

我的观点是,Optional 用于可选参数只会使方法的契约更加清晰。只需查看方法签名就可以知道此参数是可选的,不需要阅读 javadocs。但是当他不想使用那个可选参数时,不应该强迫他传递Optional.absent()

我的队友有不同的看法。他想对其进行空检查,从而强制调用者始终传递Optional.&lt;String&gt;absent()。他的观点是,我们为什么要传递一个空选项。而且getBooks("catalog123", Optional.absent()) 看起来比getBooks("catalog123", null) 更具可读性。

此方法位于我们的一个库包中,并被我们拥有的多个包使用。

您对在这种情况下使用 Optional 有何建议?

谢谢

【问题讨论】:

  • 如果允许null,您实际上有三个可能的值:无值(由null 表示)、缺少值(由Optional.absent() 表示)和现值。从我在方法设计中可以看到,我认为这不是故意的。我认为,您打算区分缺失值和当前值。由非空 Optional 明确表示的两种可能性。所以,我显然会和你的同事一起去。
  • 对我来说,Optional 最好用作返回值,强制方法的调用者检查存在/不存在,并能够区分存在、空值和不存在价值。我只会使用一个字符串作为可选参数,将其记录为可为空,并使用@Nullable 对其进行注释。您还可以提供带有单个参数的重载方法。如果你坚持使用 Optional,我会和你的同事在一起,原因与 Seelenvirtuose 相同。

标签: java guava optional-parameters


【解决方案1】:

您对在这种情况下使用 Optional 有什么建议?

避免。避免。避免。

虽然Optionalnull很酷的替代品,但在Java 中,您总是会以它为糟糕的补充。正如 Seelenvirtuose 所写,有三种可能性,您只需要两种。正如 JB Nizet 所写,它最好用作返回值,它提醒调用者需要检查。作为方法参数,它没有任何帮助。

理想情况下,可选参数就像 in 一样是可选的

getBooks(String catalogId, String categoryId = null)

这不是有效的Java。 AFAIK C++ 编译器将其转换为两种方法

getBooks(String catalogId, String categoryId)
getBooks(String catalogId)

这是你必须自己用 Java 编写的。省略参数是明确表明它是可选的最清晰的方法。将可选参数标记为@Nullable 几乎一样好。使用可空性检查工具可以帮助您避免 NPE(这是 Optional 的主要参数)。

重要的是一致性。整个班级的一致性掌握在您手中。与 JDK 保持一致意味着使用 null,至少在可预见的未来(有一天 JDK 8 Optional 可能会占上风)。

【讨论】:

  • afaik C++ 编译器只生成一个方法,但在调用中缺少默认值时将其添加为参数
  • @RemigiusStalder 您可能是对的,但是,它相当于生成两种方法并始终内联其中一个。实际上,这很有意义w.r.t。实施。但是对于用户来说,就好像有两种方法(不确定重载和继承方法的复杂情况)。
  • 没错。语义是等价的,但两个签名要求更多的入口点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
  • 2019-03-08
  • 2018-06-28
  • 1970-01-01
  • 2012-06-19
  • 2022-01-03
相关资源
最近更新 更多