Java 8:如何在流中使用异常抛出方法?

假设我有一个类和一个方法

class A {
  void foo() throws Exception() {
    ...
  }
}

现在我想为流交付的每个实例调用 foo,如下所示:A

void bar() throws Exception {
  Stream<A> as = ...
  as.forEach(a -> a.foo());
}

问:如何正确处理异常?代码不能在我的机器上编译,因为我不处理foo()可能引发的异常。的 在这里似乎没用。为什么?throws Exceptionbar


答案 1

您需要将方法调用包装到另一个方法调用中,其中不会引发已检查的异常。您仍然可以抛出任何属于 的子类。RuntimeException

一个正常的包装成语是这样的:

private void safeFoo(final A a) {
    try {
        a.foo();
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

(超类型异常用作示例,切勿尝试自己捕获它)Exception

然后你可以用以下方式调用它: .as.forEach(this::safeFoo)


答案 2

如果你想要的只是调用 ,并且你更喜欢按原样传播异常(不包装),你也可以只使用 Java 的循环(在将 Stream 变成一个带有一些技巧的可迭代之后):foofor

for (A a : (Iterable<A>) as::iterator) {
   a.foo();
}

至少,这是我在JUnit测试中所做的,我不想经历包装已检查异常的麻烦(实际上更喜欢我的测试来丢弃未包装的原始异常)


推荐