谁决定哪些例外被抑制?

时间:2012-07-22 19:22:47

标签: java exception java-7

据我所知,Java 7的抑制异常功能是一种自动功能。换句话说,在6中最终块中发生的异常会自动被抑制,有利于在资源分配时发生的异常。

因此,在这个示例中,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()就在那里。

请提供示例和用例。

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

为什么要回复新帖:

  1. 更多澄清(至少我需要他们一次阅读,特别是在catch方面)
  2. 添加了代码
  3. addSuppressed用法(catch
  4. 添加了用例/示例

    案例逐案:

    1. try - catch - finally(或try - finally)将禁止除finally阻止之外的所有异常。此外, nothing 将在抑制例外列表中,如果您触摸它,无论是否被抑制。
    2. try - 有资源 - finally会传播try例外,其中finally一个被列入抑制列表。
    3. try -...- catch - finally的工作方式类似。如果catch抛出,则会抑制try异常使其丢失,除非您手动使用addSupressed()捕获异常(将原始异常与新抛出异常绑定)。我相信这是最后一段接受的答案。
    4. 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");
          }
      }
      

      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"); } }

      所以,你没有选择被压制的东西,而 } 是为了让堆栈痕迹更加完整。

      输出:

      1. 尝试 - 捕获 - 最后,捕获抛出中断执行: catch throws, no suppression info

      2. 尝试 - 捕获 - 最后,所有抛出,捕获throwable添加尝试异常,已经最终捆绑在

      3. catch repacked, suppression info added by hand