Optional in orElse-Branch throws Exception
Optional in orElse-Branch throws Exception
所以我在使用 Optionals 时遇到了一个奇怪的行为。我想知道这是否真的是一个意图 "feature" 或什么...奇怪...
这是给定的例子:
我有一个带有 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);
其他人以前遇到过这种行为吗?这真的是可选项的行为方式吗?
这是预期的行为。 orElse
期望类型为 T
的参数(无论 Optional
的通用类型是什么。orElseThrow
returns a T
,因此它需要首先进行评估,以便将参数传递给 orElse
.
你要的是orElseGet
,需要一个Supplier<T>
。这将延迟 orElseThrow
的执行,直到 firstOptionalVar
已经被检查。
因此您的代码应如下所示:
firstOptionalVar.orElseGet(() -> secondOptionalVar.orElseThrow(IllegalArgumentException::new));
这会将 orElseThrow
部分变成一个 lambda,并且仅在需要时对其进行评估(即当 firstOptionalVar
没有可获取的值时)。
在一切的核心,您仍然只调用 Java 方法,因此适用标准 Java 评估顺序。
具体来说:secondOptionalVar.orElseThrow(IllegalArgumentException::new)
必须在 调用 firstOptionalVar.orElse()
之前计算 ,因为它提供了 firstOptionalVar.orElse()
的参数。
我看不出有什么简单的方法可以用 Optional
的标准方法解决这个问题,你总是可以用两个可选值构建一个流并获取第一个元素,否则抛出异常,但它好像有点绕。
所以我在使用 Optionals 时遇到了一个奇怪的行为。我想知道这是否真的是一个意图 "feature" 或什么...奇怪...
这是给定的例子: 我有一个带有 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);
其他人以前遇到过这种行为吗?这真的是可选项的行为方式吗?
这是预期的行为。 orElse
期望类型为 T
的参数(无论 Optional
的通用类型是什么。orElseThrow
returns a T
,因此它需要首先进行评估,以便将参数传递给 orElse
.
你要的是orElseGet
,需要一个Supplier<T>
。这将延迟 orElseThrow
的执行,直到 firstOptionalVar
已经被检查。
因此您的代码应如下所示:
firstOptionalVar.orElseGet(() -> secondOptionalVar.orElseThrow(IllegalArgumentException::new));
这会将 orElseThrow
部分变成一个 lambda,并且仅在需要时对其进行评估(即当 firstOptionalVar
没有可获取的值时)。
在一切的核心,您仍然只调用 Java 方法,因此适用标准 Java 评估顺序。
具体来说:secondOptionalVar.orElseThrow(IllegalArgumentException::new)
必须在 调用 firstOptionalVar.orElse()
之前计算 ,因为它提供了 firstOptionalVar.orElse()
的参数。
我看不出有什么简单的方法可以用 Optional
的标准方法解决这个问题,你总是可以用两个可选值构建一个流并获取第一个元素,否则抛出异常,但它好像有点绕。