Closeable和AutoCloseable close()方法的执行顺序

时间:2019-04-17 09:27:08

标签: java ioexception try-with-resources autocloseable

有人可以向我解释这里发生了什么以及以什么顺序发生?输出对我来说没有任何意义。

输出为T 1 IOE F。

代码是:

import java.io.Closeable;
import java.io.IOException;

public class TestRes {
    public static void main(String[] args) {
    try (
            MyResource11 r1 = new MyResource11();
            MyResource21 r2 = new MyResource21();
            ) 
        {
            System.out.print("T ");
        } catch (IOException ioe) {
            System.out.print("IOE ");
        } finally {
            System.out.print("F ");
        }
    }
}

class MyResource11 implements AutoCloseable {
    public void close() throws IOException {
        System.out.print("1 ");
    }
}

class MyResource21 implements Closeable {
    public void close() throws IOException {
        throw new IOException();
    }
}

2 个答案:

答案 0 :(得分:4)

try-with-resources按照与它们声明的顺序相反的顺序关闭相反的资源。因此该代码:

  1. 打印T
  2. try-with-resources语句尝试关闭r2
  3. 这引发异常
  4. try-with-resources语句成功关闭r1,并输出1
  5. 运行异常块(针对r2的异常)并输出IOE
  6. 运行finally块,输出F

值得一读的try-with-resources part of the JLS,其中包括未整理的try-with-resources语句的代码示例(例如,仅包含try / catch / {{1 }})。在该部分:

  

以与初始化资源相反的顺序关闭资源。仅当资源初始化为非空值时,它才关闭。一个资源关闭的异常不会阻止其他资源的关闭。如果初始化程序,try块或资源关闭之前引发了异常,则可以抑制这种异常。

答案 1 :(得分:2)

您的代码是的快捷方式

public static void main(String[] args) {
    try {
        MyResource11 r1 = new MyResource11();
        try {
            MyResource21 r2 = new MyResource21();
            try {
                System.out.print("T ");
            } finally {
                r2.close();
            }
        } finally {
            r1.close();
        }
    } catch (IOException ioe) {
        System.out.print("IOE ");
    } finally {
        System.out.print("F ");
    }
}