【问题标题】:Optional in orElse-Branch throws Exception [duplicate]orElse-Branch中的可选抛出异常[重复]
【发布时间】:2016-07-25 23:24:52
【问题描述】:

所以我正在使用 Optionals 并遇到了一个奇怪的行为。我想知道这是否真的是一个有意的“功能”或什么......奇怪......

这是给定的示例: 我有一个带有 Optional 的方法,我想在其 orElse 中评估另一个可选。如果另一个 Optional 不存在,我将引发 IllegalArgumentException:

firstOptionalVar.orElse(secondOptionalVar.orElseThrow(IllegalArgumentException::new));

现在,如果 secondOptionalVar 是一个空的 Optional,即使 firstOptionalVar 存在,它也会引发 IllegalArgumentException。这对我来说似乎不对。如果firstOptionalVar 不存在,我希望它只会引发 IllegalArgumentException。

使用 java7 方法来解决这种行为并不是什么大问题,例如:

firstOptionalVar.isPresent() ? firstOptionalVar.get() : secondOptionalVar.orElseThrow(IllegalArgumentException::new);

以前有没有其他人经历过这种行为?这真的是可选项的行为方式吗?

【问题讨论】:

  • flatMap 不幸地相反。
  • 异常的答案可以在链接的问题或你得到的答案中找到。请注意,您要执行的“或”操作将在 Java 9 上可用:stackoverflow.com/questions/24599996/…
  • 感谢您的回答。 @resueman 的解决方案对我有用,但很高兴知道 java9 将如何处理这种情况:)

标签: java exception-handling java-8 optional


【解决方案1】:

这是预期的行为。 orElse 需要一个 T 类型的参数(无论 Optional 的泛型类型是什么。orElseThrow 返回一个 T,因此需要先评估它,以便将参数传递给 orElse .

你想要的是orElseGet,它需要一个Supplier<T>。这将延迟orElseThrow 的执行,直到firstOptionalVar 已经被检查之后。

所以你的代码应该是这样的:

firstOptionalVar.orElseGet(() -> secondOptionalVar.orElseThrow(IllegalArgumentException::new));

这会将 orElseThrow 部分转换为 lambda,并且仅在需要时对其进行评估(即当 firstOptionalVar 没有要获取的值时)。

【讨论】:

  • 不错的一个。这是我一直试图弄清楚的解决方案。 :)
  • 非常感谢。这正是我想要的。
【解决方案2】:

在一切的核心,您仍然只是调用 Java 方法,因此标准的 Java 求值顺序适用。

具体来说:secondOptionalVar.orElseThrow(IllegalArgumentException::new) 必须在调用firstOptionalVar.orElse() 之前进行评估,因为它提供了firstOptionalVar.orElse() 的参数。

我看不到使用Optional 的标准方法解决此问题的任何简单方法,您始终可以从两个选项中构建一个流并获取第一个元素或抛出异常,但这似乎有点令人费解.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-23
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多