终端操作(例如forEach)是否可以重新抛出已检查的异常?

时间:2014-02-11 00:10:51

标签: java java-8 java-stream checked-exceptions

我有一个删除某些文件的方法:

void deepDelete(Path root) {
    Files.walk(root)
            .filter(p -> !Files.isDirectory(p))
            .forEach(p -> { try { Files.delete(p); }
                            catch (IOException e) { /* LOG */ }
            });
}

try / catch块降低了操作的可读性,尤其是使用方法引用时:

void deepDelete(Path root) throws IOException {
    Files.walk(root)
            .filter(p -> !Files.isDirectory(p))
            .forEach(Files::delete); //does not compile
}

不幸的是,代码无法编译。

有没有办法在终端操作中应用抛出已检查异常的操作,只是“重新抛出”任何异常?

据我所知,我可以编写一个包装器,将已检查的异常转换为未经检查的异常,但如果可能,我宁愿坚持使用JDK中的方法。

2 个答案:

答案 0 :(得分:1)

据我所知:不。我使用this techempower article作为我的java8指南,它非常明确(参见“异常透明度”一节)。

答案 1 :(得分:0)

如果您声明此方法:

@SuppressWarnings("unchecked")
static <T extends Throwable> RuntimeException sneakyThrow(Throwable t) throws T {
    throw (T)t;
}

然后你可以这样做:

try {
    Files.delete(p);
} catch (IOException e) {
    throw sneakyThrow(e);
}

这会绕过已检查的异常规则并抛出原始IOException而不进行包装,尽管您仍然必须抓住它并且重新抛出。我不是说这是一个好主意,但它是 的想法。