试用资源关闭订单

Ali*_*iuk 6 java jdbc java-io try-with-resources autocloseable

我正在查看 Java 中的 try-with-resources 示例,我了解以下内容:

try (Connection conn = DriverManager.getConnection(url, user, pwd);
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery(query);) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

所以,关闭的顺序是:

rs.close();
stmt.close();
conn.close();
Run Code Online (Sandbox Code Playgroud)

这是完美的,因为一个连接有一个语句,而一个语句有一个结果集。

但是,在以下示例中,关闭的顺序我认为与预期相反:

示例 1:

try (FileReader fr = new FileReader(file);
     BufferedReader br = new BufferedReader(fr)) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

关闭顺序为:

br.close();
fr.close();
Run Code Online (Sandbox Code Playgroud)

示例 2:

try (FileOutputStream fos = new FileOutputStream("testSer.ser");
    ObjectOutputStream oos = new ObjectOutputStream(fs);) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

关闭顺序为:

oos.close();
fos.close();
Run Code Online (Sandbox Code Playgroud)

这些例子正确吗?我认为这些例子中的结束应该有所不同,因为:

  1. 在示例 1 中,BufferedReader 有一个 FileReader。
  2. 在示例 2 中,ObjectOutputStream 有一个 FileOutputStream。

And*_*ner 6

顺序是相同的:它总是与指定资源的顺序相反。来自JLS

资源以与它们被初始化的顺序相反的顺序关闭。

但是,如果以后指定的资源本身调用close()指定的早期资源的方法(就是这种情况与BufferedReaderObjectOutputStream),它可能看起来像他们没有在预期的顺序发生(这close()将被调用多次)。


Ali*_*iuk 0

我认为我说的“连接有一个声明,一个声明有一个结果集”是不对的。也许是相反的“结果集有一个语句,一个语句有一个连接”,或者至少是“一个结果集是由一个语句创建的,一个语句是由一个连接创建的”。

所以我认为:

try (Parent parent = new Parent();
     Child child = parent.createChild();) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

相当于:

try (Parent parent = new Parent();
     Child child = new Child(parent);) {
    ...
}
Run Code Online (Sandbox Code Playgroud)