【问题标题】:Should Optional.ofNullable() be used for null check?是否应该使用 Optional.ofNullable() 进行空检查?
【发布时间】:2019-02-01 22:32:15
【问题描述】:

哪种空检查更可取?

Optional.ofNullable(port).ifPresent(settings::setPort);

if (port != null) {
   settings.setPort(port);
}

【问题讨论】:

  • 适合谁?这是一个基于意见的问题。哪一个会为计算机和下一个人阅读代码的大脑带来更多开销?
  • 这是基于意见的。但我更喜欢第二种选择。更具可读性。另外,Optional 还有另一个目的。
  • 只是为了if,我不会,至少对于orElse的使用,这变得更有趣了。
  • @Kayaman 这并不罕见。尤其是其中一些点可能会相互作用。

标签: java lambda java-8 null optional


【解决方案1】:

在 Java 中,Optional 值是表示存在或不存在的位与任意引用类型 T 或原语 intlongdouble 的值的融合。

在从方法返回值时,融合这些特别有用,因为方法只有一个返回值。通常需要使用特殊值,例如在引用类型的情况下使用null,或者在int 的情况下使用-1,作为指示“无值”情况的标记。使用Optional作为返回值,避免了调用者不小心误用sentinel值作为真正返回值的问题。

鉴于此,代码行如

Optional.ofNullable(port).ifPresent(settings::setPort);

很奇怪,它在行的第一部分将值与存在/不存在位融合在一起,然后在行的第二部分立即将它们分开。这增加了最终相当简单的任务的复杂性:检查port 是否为非空并有条件地执行某些操作。替代代码sn -p:

if (port != null) {
    settings.setPort(port);
}

准确地表达了它的作用。

确实,if 语句比Optional 链占用更多的垂直空间。 Optional 链更密集,但也更难理解:一个糟糕的权衡。

【讨论】:

  • 这是这里给出的唯一正确答案。它值得更多+1。 Java8 在行动中促进了Optional.ofNullable(port).ifPresent(settings::setPort);Optional 的使用。但是根据一些书籍,Optional 存在严重的性能问题。所以它应该只用作函数的返回值。
  • @RavindraRanwala 我完全不同意这一点——我们在代码中使用这种模式,不多,但我们确实这样做了。问题是,对于我们的团队来说——显然这更容易阅读(包括我自己)。
  • 可选是语法糖,需要自费。对于简单的空检查,最好使用传统的空检查
【解决方案2】:

虽然,您在问题中发布的 sn-p 只是避免丑陋的null-check 的一种简单方法,但它是有效的、正确的和 null 安全的。在这种情况下,请遵循您的个人喜好。

Optional 的真正强大之处在于以下方法:

例如,假设您想从 port 获取另一个值以添加到列表中,如果 portnull,则避免 NPE:

Optional.ofNullable(port).map(port::getSomeValue).ifPresent(settings::setPort);

此外,请避免以下我经常看到的null-check 的无意义替换:

if (Optional.ofNullable(port).isPresent()) {
    settings.setPort(port);
}

【讨论】:

  • .map(Port::getSomeValue) 保持简单。你真的经常看到最后一点吗?太可惜了!
【解决方案3】:

何时使用它取决于几个因素。 如果port 是类中的一个属性,那么使用Optional 可能有点矫枉过正。 (并且不要使用Optionals 作为属性,因为它们是not serializbie

我认为Optionals 在编写库时非常有用。

public Optional<Integer> getPort()

比其他开发者更具描述性

// Returns null if not set
public Integer getPort()

【讨论】:

  • 返回null 通常是隐含的,所以这并不值得评论,也不会令人惊讶的是让null 回来。 Optional 有它的位置,但它不会自动替换可能返回 null 的方法。
  • @Kayaman 也许我的例子过于简单了,因为“简单”的 get 方法。像其他任何东西一样在有意义的地方使用它。但是可能有一些方法不是那么隐含的,或者是参数让它更清楚。
  • 确实如此,但就像这个问题所示,有些人认为Optionalnull 的替代品,但事实并非如此。有点像人们认为流是正常循环的替代品,而您对通过用流替换循环来“改进”代码有疑问。
猜你喜欢
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
  • 2014-01-01
  • 2015-04-24
  • 2019-07-21
  • 1970-01-01
相关资源
最近更新 更多