18

如何避免Exception在尝试从 anOptional或在使用时显式地抛出一个值Optional.get

目前,这可能通过 API 得到保护orElseThrow

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

然而,get在尝试访问类似

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

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

4

3 回答 3

52

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

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

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

于 2018-03-07T19:38:23.240 回答
5

从我的角度来看,Optional.get()是代码异味。很多时候结合在一起Optional.isPresent(),就完全违背了目的和想法Optional.get()。这是一个更完整的推理和讨论:

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

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

于 2018-03-07T18:30:40.110 回答
3

另一种获取可选值而不是值的替代方法Optional.get(这很可能无法满足用户的期望)是用 JDK10 中引入的更详细的 API 替换它,称为Optional.orElseThrow(). 用作者的话说——

Optional.get()是一个“有吸引力的麻烦”,对程序员来说太诱人了,导致经常出错。人们不希望 getter 抛出异常。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<? extends X> exceptionSupplier)a,该值内联到消费者使用的现有实现作为显式替代。

于 2018-03-07T18:21:24.133 回答