try-with-resources 什么时候关闭资源?

When does try-with-resources close the resource?

我正在为面向对象编程的秋季考试做准备,我们得到的一种任务是提供代码的输出,这些代码通常包含一些异常处理问题。

现在我的问题是 try-with-resources 什么时候关闭它的资源,因为我的输出严格依赖于实现 AutoCloseable 的 class 的输出。

在提供的代码中,我不明白为什么 "close 1" 输出出现在 "close 40" 之前,或者为什么对象 A(40) 在此块的末尾关闭。是因为A(50)和A(40)是同类型吗?

我的主要问题是 AutoCloseable 何时关闭给定资源,例如当 i=1 时的示例 m1:

1) A(1) 已创建 1b) try块被执行 2) A(1) 是封闭的 3) ArrayIndexOutOfBoundsException 是否被处理?

public class Main {
    public static void main(String[] args) {
          int[] arr = new int[] { 15, 10 };
          for(int i=1; i>=-1; i--){
              try(A a40 = new A(40)) {
                  m1(arr, i);
                  A a50 = new A(50);
              }
              catch(ArrayIndexOutOfBoundsException e) {
                System.out.println("array exc");
              }
              catch(Exception e) {
                System.out.println("main exc");
                break;
              }
              finally {
                System.out.println("main finally");
              }
          }
          System.out.println("main done");
        }

        private static void m1(int[] arr, int i) throws Exception {
          try(A a1 = new A(i)) {
            m2(arr[i] + arr[i+1], i);
          }
          catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("m1 exc");
          }
          System.out.println("m1 done");
        }

        private static int m2(int x, int y)  {
           int r = 0;
           try{
               A a2 = new A(x+y);
               r = x / y;
           }
           finally {
            System.out.println("m2 finally");
           }
           System.out.println("m2 done");
           return r;
        }
}

和class实现AutoCloseable的A:

public class A implements AutoCloseable {
      private int x;
      public A(int x){
        this.x = x;
           System.out.println("A " + x);
      }
      @Override
      public void close() throws Exception {
        System.out.println("close " + x);
      }
}

这里是所提供代码的输出:

A 40
A 1
close 1
m1 exc
m1 done
A 50
close 40
main finally
A 40
A 0
A 25
m2 finally
close 0
close 40
main exc
main finally
main done

规范对此很清楚。

14.20.3. try-with-resources

A try-with-resources statement is parameterized with local variables (known as resources) that are initialized before execution of the try block and closed automatically, in the reverse order from which they were initialized, after execution of the try block.

你的例子有点绕。尝试简化它。您对两种情况感兴趣:在 try 块中抛出异常,在 try 块中未抛出异常。您的调试消息内容丰富,因此您将能够轻松跟踪流程。

您可能想查看反编译的 .类 以查看实际生成的内容。