为什么不能在方法级别抛出 java 流中的已检查异常?

Why can't checked exceptions in a java stream be thrown at method level?

我一直在学习并发和流 API 并遇到了这个。 offerLast() 方法可以抛出 InterruptedException,所以我知道我必须处理它。我不明白的是为什么我不能通过添加 throws Exception 在方法级别抛出它?因为它 code 无法编译。

static BlockingDeque<Integer> queue = new LinkedBlockingDeque<>();

public static void testing() throws Exception {
    IntStream.iterate(1, i -> i+1).limit(5)
            .parallel()
            .forEach(s -> queue.offerLast(s, 10000, TimeUnit.MILLISECONDS));
}

我知道可以通过将它包围在 try/catch 中或创建一个处理 errorwrapper method 来解决,但我仍在尝试理解为什么会这样不能在方法级别抛出。

因为 lambda 表达式并不总是立即求值。

让你拥有这个:

public Supplier<String> giveMeASupplier() throws Exception {
    return () -> someMethodThatThrowsCheckedException()
}

根据您的说法,以上方法可行。对吗?

现在用另一种方法,我可以这样做:

Suppler<String> supplier = null;
try {
    supplier = giveMeASupplier() // no exception is thrown here.
} catch (Exception ex) {
    ex.printStackTrace();
}
if (supplier != null) {
    System.out.println(supplier.get()); // this might throw an exception! Yet it's not in a try...catch!
}

现在,如果 supplier.get() 抛出异常,您认为会发生什么情况?有什么可以抓的吗?不。如果 catch 以某种方式在获取 运行 之前阻塞几行,那么它会 真的 很奇怪。

简单的答案是您指的 "method" 是 Consumer.accept,而不是 YourClass.testing

lambda s -> queue.offerLast(s, 10000, TimeUnit.MILLISECONDS)java.util.function.Consumer.accept(T) 的一个实现,它没有声明它可以抛出 InterruptedException
而且这种行为并不是流特有的,无论哪里定义了lambda表达式,它都必须符合它实现的功能接口的抽象方法的签名。