Optional.get() 与重载 Optional.orElseThrow()

Optional.get() versus overloaded Optional.orElseThrow()

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

目前,这可能由 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 怎么办?

另一种获取可选值而不是 Optional.get (which more likely than not fails to keep up with user's expectations) is to replace it with a more verbose API introduced in JDK10 termed as Optional.orElseThrow(). In author's words 的方法 -

Optional.get() is an "attractive nuisance" and is too tempting for programmers, leading to frequent errors. People don't expect a getter to throw an exception. A replacement API for Optional.get() with equivalent semantics should be added.

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) 实现备选方案。

在我看来,Optional.get() 是代码味道。经常与 Optional.isPresent() 结合使用,它完全违背了 Optional.get() 的目的和想法。这里有更完整的推理和讨论:

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

所以干脆不要使用 Optional.get()。如果您想 return null 获取缺失值,请调用 Optional.orElse(null).

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

在 Java 9 的时间范围内,我们提议弃用 Optional.get(),但 public 对此的回应是......让我们说冷。作为更小的步骤,我们在 10 中引入了 orElseThrow()(请参阅 https://bugs.openjdk.java.net/browse/JDK-8140281)作为 get() 当前有害行为的更透明命名的同义词。 IDE 会警告无条件使用 get(),但不会警告 orElseThrow(),这是在教人们更好地编码方面向前迈出的一步。从某种意义上说,问题是对当前情况的 "glass half empty" 看法; get() 还是有问题。

我们很乐意在未来的版本中进一步改善这种情况,但可能需要一些时间才能吸引更多社区成员。