【问题标题】:Try-with-resources close orderTry-with-resources 关闭订单
【发布时间】:2019-03-12 23:07:37
【问题描述】:

我正在查看 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。

【问题讨论】:

  • br 依赖于fr(就像rs 依赖于stmt 依赖于conn),所以br 应该首先关闭(并且br也会关闭fr 本身)。您的期望是错误的;你可能想解释一下为什么你认为应该先关闭fr(和fos)。

标签: java jdbc java-io try-with-resources autocloseable


【解决方案1】:

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

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

但是,如果后面指定的资源自己调用前面指定的资源的 close() 方法(如 BufferedReaderObjectOutputStream 的情况),它们可能看起来不像预期的那样发生顺序(并且 close() 将被多次调用)。

【讨论】:

    【解决方案2】:

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

    所以我认为:

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

    相当于:

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

    【讨论】:

      猜你喜欢
      • 2017-12-04
      • 2014-05-05
      • 2020-01-01
      • 2016-09-29
      • 2011-10-16
      • 1970-01-01
      • 2015-08-13
      • 2017-05-06
      • 2019-09-06
      相关资源
      最近更新 更多