尝试资源关闭订单

时间:2018-10-08 09:45:17

标签: 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);) {
  ...
}

因此,关闭顺序为:

rs.close();
stmt.close();
conn.close();

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

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

示例1:

try (FileReader fr = new FileReader(file);
     BufferedReader br = new BufferedReader(fr)) {
  ...
}

关闭顺序为:

br.close();
fr.close();

示例2:

try (FileOutputStream fos = new FileOutputStream("testSer.ser");
    ObjectOutputStream oos = new ObjectOutputStream(fs);) {
    ...
}

关闭顺序为:

oos.close();
fos.close();

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

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

2 个答案:

答案 0 :(得分:3)

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

  

关闭资源的顺序与初始化时的顺序相反。

但是,如果后指定资源本身调用了前指定资源的close()方法(与BufferedReaderObjectOutputStream一样),则看起来像它们不会按预期的顺序发生(并且close()将被多次调用)。

答案 1 :(得分:0)

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

所以我认为:

try (Parent parent = new Parent();
     Child child = parent.createChild();) {
    ...
}

等效于:

try (Parent parent = new Parent();
     Child child = new Child(parent);) {
    ...
}