3

据我了解,Java 7 的抑制异常功能是自动的。换句话说,在 6 中的 finally 块中发生的异常会被自动抑制,以支持在资源分配时发生的异常。

因此,在此示例中,a) 打开资源和 b) 关闭资源或 c) 可能两者都可能出错。

据我了解,Java 7 将抛出打开时发生的异常,我们可以要求它给我们抑制的异常,这些异常发生在其他地方。

    try (BufferedReader inputReader = Files
            .newBufferedReader(Paths.get(new URI(
                    "file:///Users/me/Desktop/readme.txt")), Charset
                    .defaultCharset())) {
        String inputLine;
        while ((inputLine = inputReader.readLine()) != null) {
            System.out.println(inputLine);
        }
    } 

问题是..程序员可以决定什么被压制?毕竟,public addSuppressed()有。

请提供示例和用例。

4

2 回答 2

4

这不是任意的——被抑制的异常是那些会掩盖导致try块失败的主要异常的异常——这就是块中的异常finally。此功能可确保您获得整个构造中抛出的所有异常,但您捕获的异常将是更重要的异常。

你不能选择被压制的东西。当然,方法就在那里,否则整个事情都行不通。如果您愿意,您可以编写自己的异常处理代码并addSuppressed随意使用。

于 2012-07-22T19:27:49.000 回答
0

为什么新回复:

  1. 更多说明(至少我读过一次就需要它们,尤其是在catch侧面)
  2. 添加代码
  3. 添加了用例/addSuppressed用法示例(catch

逐案:

  1. 旧的try- catch- finally(或try- finally)将抑制除finally块之外的所有异常。此外,如果您触摸它,则任何内容都不会出现在被抑制的例外列表中,无论某些东西是否被抑制。
  2. try-with-resources-finally将传播try异常,其中finally一个在禁止列表中。
  3. try-...- catch-finally工作方式类似。如果catch抛出,它会抑制try异常使其丢失,除非您addSupressed()手动使用捕获异常(将原始异常绑定到正在抛出的新异常)。我相信这是上一段中接受的答案所涵盖的情况。

public class WhichIsSupressedTryCatchOrFinally {

public static void main(String[] args) {
    try {
//            tryOrFinally(); // throws finally, try one is lost
//            tryCatchOrFinally(); // as above, no suppression info

//            tryWithResourcesOrFinally(); // throws try, adds finally one to it though automatically
        tryWithResourcesCatchOrFinallyCatchThrows();
        tryWithResourcesCatchOrFinallyByHand(); // throws catch, but adding "by hand" try, adds finally also
    } catch (Exception e) {
        e.printStackTrace();
        // System.out.println(Arrays.toString(e.getSuppressed())); -> not needed!
    }
}

static class AResource implements AutoCloseable {

    @Override
    public void close() throws NumberFormatException {
        throw new NumberFormatException("did not see that one coming, did'ya?");
    }
}
private static void tryWithResourcesOrFinally() throws FileNotFoundException {
    try (AResource a = new AResource()) {
        throw new FileNotFoundException("try");
    }
}

private static void tryWithResourcesCatchOrFinallyCatchThrows() throws Exception {
    try (AResource a = new AResource()){
        throw new IOException("try");
    } catch (Exception e) {
        throw new NoSuchElementException("catch");
    }
}

private static void tryWithResourcesCatchOrFinallyByHand() throws Exception {
    try (AResource a = new AResource()){
        throw new IOException("try");
    } catch (Exception e) {
        NoSuchElementException aCatch = new NoSuchElementException("catch");
        aCatch.addSuppressed(e);
        throw aCatch;
    }
}

private static void tryOrFinally() throws Exception {
    try {
        throw new IOException("try");
    } finally {
        throw new Exception("finally");
    }
}

private static void tryCatchOrFinally() throws Exception {
    try {
        throw new IOException("try");
    } catch (Exception e) {
        throw new NoSuchElementException("catch");
    } finally {
        throw new Exception("finally");
    }
}

}

所以,你不要选择什么被抑制addSuppressed而是让堆栈跟踪更完整。

输出:

  1. try - catch - finally,catch 抛出中断执行: 捕捉抛出,没有抑制信息

  2. try - catch - finally,所有 throws,catch throwable 都被添加了 try 异常,它已经绑定了 finally 一个

捕获重新包装,手动添加的抑制信息

于 2015-09-16T23:35:06.853 回答