【问题标题】:Optional.get() versus overloaded Optional.orElseThrow()Optional.get() 与重载 Optional.orElseThrow()
【发布时间】:2023-03-31 22:11:02
【问题描述】:

在尝试从Optional 获取值或使用Optional.get 时,如何避免显式抛出Exception

目前,这可能通过 API orElseThrow 进行保护:

// exception could be replaced with any other
Integer opt = anyOddInStream.orElseThrow(
                           () -> new NoSuchElementException("No value present"));

然而,在尝试访问类似

// the following not only just fails but throws an exception as well
Integer previous = anyOddInStream.get();

如果想确保Optional 有一个值,如果没有,他们不想继续向前传播null 怎么办?

【问题讨论】:

  • @shmosel 没关系。 “NoSuchElementException 如果不存在值”是 API。关键是抛出异常的不是 OP。
  • 我绝对不明白这个添加,是准备删除/弃用get吗?我真希望@StuartMarks 能来这里……
  • @Eugene Brian 已经回答了。但弃用get() 仍然存在,尽管在继续之前我们还有更多工作要做。 (另请注意,除非该人之前发表过评论,否则@-通知不起作用,因此我没有从您的评论中收到通知。我只是碰巧看到它,因为我监控了 Optional 标签。)
  • 这篇文章很有用(我只是把它当作一个骗子),但问题是真的难以阅读。请尽量说清楚。
  • @shmosel 是的,在我问这个问题的时候,我认为问题应该是什么和当前已经提供的重载实现之间存在着很大的差距。实际上,回过头来看,问题只是寻求使用getorElseThrow 的区别。老实说,就目前的情况而言,我自己觉得它们都让消费者陷入了麻烦的境地。 (意见)

标签: java optional java-10


【解决方案1】:

Java 8 是对平台的巨大改进,但我们犯的少数错误之一是 Optional.get() 的命名,因为这个名称只是邀请人们调用它而不调用 isPresent(),破坏了使用的全部意义Optional 首先。 (如果这是我们在如此大的版本中犯的最严重的错误,那么我们做得很好。)

在 Java 9 时间范围内,我们提议弃用 Optional.get(),但公众对此的反应是……让我们说冷漠吧。作为一个较小的步骤,我们在 10 中引入了orElseThrow()(参见https://bugs.openjdk.java.net/browse/JDK-8140281)作为get() 当前有害行为的更透明命名的同义词。 IDE 会警告无条件使用 get(),但不会警告 orElseThrow(),这是在教人们更好地编码方面向前迈出的一步。从某种意义上说,问题是对当前形势的“半空玻璃”看法; get() 还是有问题的。

我们希望在未来的版本中进一步改善这种情况,但可能需要一些时间才能让更多的社区参与进来。

【讨论】:

  • 没有比 Java 语言架构师 Brian Goetz 先生本人更好的权威来源了!!! imo get() 应该在 Java 11 中被弃用/删除,所以人们会停止使用它与 isPresent 一起使用,不幸的是,这对新的 Java 开发人员来说是一个有吸引力的反模式。也许有时需要为社区的利益做一些事情,即使社区一开始不会欣赏它......
【解决方案2】:

在我看来,Optional.get() 是代码异味。经常与Optional.isPresent()结合使用,完全违背了Optional.get()的目的和理念。下面是更完整的推理和讨论:

http://royvanrijn.com/blog/2016/04/deprecating-optional-get/

所以不要使用Optional.get()。如果您想为缺失值返回null,请调用Optional.orElse(null)

【讨论】:

  • @nullpointer 通常你可以使用orElseorElseGetorElseThrowmap 实现几乎所有目标。
  • @nullpointer 我不确定你想对上一条评论说什么。我的观点是,你不一定需要get() 来表示 “如果,一个人想确保 Optional 要么有一个值,如果没有,他就不想继续向前传播 null” .
  • @TalAvissar Object x = optional.orElse(null); 对我来说已经足够了。
  • @lexicore 这对我来说正确答案(+1),似乎get 将被弃用。他们可能在他们的心智模型中有番石榴......
  • @TalAvissar 我在 C# 中 讨厌 顺便说一句(可能只是我),就像代码一直在尖叫或想知道,再次,它可能只是我
【解决方案3】:

获取可选值而不是 Optional.get 的另一种方法是用 JDK10 中引入的更详细的 API 替换它,称为 @987654322 @。在author's words -

Optional.get() 是一个“有吸引力的麻烦”,太诱人了 程序员,导致经常出错。 人们并不期望有吸气剂 抛出异常。Optional.get() 的替换 API 应添加等效语义。

Optional<Integer> anyOddInStream = Stream.of(2, 4, 6, 8)
                                         .filter(x -> x % 2 == 1)
                                         .findAny();
// one could be well aware of the possible exception handling while reading this 
var current = anyOddInStream.orElseThrow(); 

注意:- 这两个 API 的底层实现是相同的,但后者更清楚地读出 NoSuchElementException 将是如果值不存在,则默认抛出,该值内联到消费者使用的现有Optional.orElseThrow(Supplier&lt;? extends X&gt; exceptionSupplier) 实现作为显式替代。

【讨论】:

    猜你喜欢
    • 2016-12-08
    • 2016-12-28
    • 2017-08-29
    • 2019-12-25
    • 2010-12-18
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多