Guava可选用于例外的快捷方式?

Oli*_*ire 17 java guava

在不存在Optional的情况下,我一直在写特定的例外投掷者.

例如:

Optional<?> optional = ...;
if (!optional.isPresent()) {
  throw new MyException();
}
Object result = optional.get();
Run Code Online (Sandbox Code Playgroud)

我发现这段代码不是很流畅,特别是使用了爆炸(!).我更喜欢写一些类似的东西:

Optional<?> optional = ...;
Object result = optional.orThrow(MyException.class);
Run Code Online (Sandbox Code Playgroud)

我还没有找到番石榴这样的捷径吗?

Lou*_*man 21

作为Guava开发人员,让我尝试在这里解压缩逻辑.直接回答问题的原始问题和评论主题:

绝对是这样的,我们试图强迫Guava用户尊重我们良好的编程习惯标准.(我们的标准受到例如Effective Java的强烈影响.)

也就是说,我同意在这个特定问题中你所指的行为有很好的用例:"如果没有,就抛出异常." 也许你正在实现一个可以双向访问的类 - 一个带有Optional返回值的方法,一个假设值始终存在的方法,否则抛出异常.例如,Deque接口提供peek,poll和offer的特殊值和异常抛出版本.

尽管如此,据我所知,真正的番石榴方式是......

if (value.isPresent()) {
  return value.get();
} else {
  throw new MyException();
}
Run Code Online (Sandbox Code Playgroud)

您建议的"orThrow"方法需要反射(!!),不允许您使用有用的消息等自定义异常."正常方式"是完全可读和更有效的.

有时候Guava没有提供明确的支持,因为对于那些用例,我们认为最好只采用"正常方式".我想这就是这种情况.

  • 好吧,`orThrow()`方法并不特别需要反射:可以考虑将`Exception`的实例委托给`Supplier`或`Function`.无论如何,主要的一点是,"真正的番石榴方式做到这一点"重复大约50次,大约有10个不同的例外,并且只有自Guava 10以来生成的新代码!我们不想一次又一次地复制那种代码.我们已经创建了几个辅助方法(每个'Exception`构造函数+附加组件1个),这对我们来说已经足够了.我只想知道是否存在替代方案,而不是.我不会开票. (4认同)

Oli*_*ire 16

这是值得什么,Java的8位的OptionalorElseThrow(Supplier),允许请求的行为方法.

它是这样使用的:

Optional<Object> reference = Optional.empty()
reference.orElseThrow(MyOwnException::new); // Throws a new MyOwnException
Run Code Online (Sandbox Code Playgroud)

此外,添加了Java 10中的方法,如果没有值orElseThrow(),则抛出a NoSuchElementException.

Optional<Object> reference = Optional.empty();
reference.orElseThrow(); // Throws a new NoSuchElementException
Run Code Online (Sandbox Code Playgroud)


Tim*_*imK 13

这是另一种不添加Guava的方法:

Object result = optional.or(new Supplier() {
    public Object get() {
        throw new MyException();
    }
});
Run Code Online (Sandbox Code Playgroud)

必须取消选中MyException,但这确实允许您将参数传递给其构造函数.当然,如果您正在做很多事情,您可以将供应商存储在某个地方,并在您需要的每个地方使用它.

Object result = optional.or(SomethingIsMissing.INSTANCE);
Run Code Online (Sandbox Code Playgroud)