try-with-resources 何时关闭资源?

3

我正在为面向对象编程的秋季考试做准备,我们需要完成一种类型的任务,即从通常包含一些异常处理问题的代码中提供输出。

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

在提供的代码中,我不明白为什么“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;
        }
}

而类A实现了AutoCloseable接口:

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
1个回答

3

在这方面,规范是非常清晰的。

14.20.3. try-with-resources

try-with-resources语句使用本地变量(称为资源)进行参数化,在执行try块之前初始化并在执行try块后以与初始化相反的顺序自动关闭

你给出的例子有些复杂,请尝试简化。你感兴趣的有两种情况:在try块中抛出异常或者在try块中未抛出异常。你的调试信息很有帮助,所以你将能够轻松跟踪代码流程。

你可能需要查看反编译的.class文件,以了解实际生成的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接