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

Posted

技术标签:

【中文标题】Closeable 和 AutoCloseable close() 方法的执行顺序【英文标题】:Order of execution of Closeable and AutoCloseable close() methods 【发布时间】:2019-04-17 09:27:08 【问题描述】:

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

输出为 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();
    

【问题讨论】:

【参考方案1】:

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

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

值得阅读try-with-resources part of the JLS,其中包括未解开的try-with-resources 语句的代码示例(例如,仅具有try/catch/finally 的等效代码)。从该部分:

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

【讨论】:

【参考方案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 ");
    

【讨论】:

以上是关于Closeable 和 AutoCloseable close() 方法的执行顺序的主要内容,如果未能解决你的问题,请参考以下文章

AutoCloseable.close() 方法是不是破坏了 Java 的向后兼容规则

JDK7 AutoCloseable

Java IO 之 InputStream

NIO通道简介

清理多个不可关闭资源时减少嵌套

The type java.lang.AutoCloseable cannot be resolved. It is indirectly referenced from required .clas