我应该在 try-with-resources 语句中声明每个资源吗?

Posted

技术标签:

【中文标题】我应该在 try-with-resources 语句中声明每个资源吗?【英文标题】:Should I declare EVERY resource in try-with-resources Statement? 【发布时间】:2019-03-22 03:56:14 【问题描述】:

在我搜索过的许多 try-with-resource 示例中,Statement 和 ResultSet 是分别声明的。正如 Java 文档中提到的,资源的 close 方法是按照它们创建的相反顺序调用的。

try (Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery(sql) ) 

 catch (Exception e) 


但现在我的函数中有多个查询。

我可以在一行中创建 Statement 和 ResultSet 吗?我的代码是这样的:

try (ResultSet rs = con.createStatement().executeQuery(sql);
     ResultSet rs2 = con.createStatement().executeQuery(sql2);
     ResultSet rs3 = con.createStatement().executeQuery(sql3)) 

 catch (Exception e) 


如果我只在一行中声明,是否仍然关闭ResultSet和Statement的资源?

【问题讨论】:

【参考方案1】:

仔细看会发现这个概念叫做try-with-resources

注意复数!整个想法是,您可以在该单个语句中声明一个或多个资源,并且 jvm 保证正确处理。

换句话说:当资源在语义上属于一起时,最好将它们一起声明。

【讨论】:

con.createStatement().executeQuery(sql2); 创建一个 Statement 对象和一个 ResultSet 对象。是不是说 statement 和 ResultSet 对象的资源在语义上属于同一类,两个资源都会自动关闭? @edyucheng 是的,当他们“属于”在一起时,这似乎是合理的。但请理解,这些细节实际上取决于您的整体设计/环境。除此之外,感谢您的快速接受;-)【参考方案2】:

是的,它的工作原理与您在问题中提出的完全一样,多个语句用分号分隔。

您可以在 try-with-resources 语句中声明一个或多个资源。以下示例检索打包在 zip 文件 zipFileName 中的文件的名称,并创建一个包含这些文件名称的文本文件:

 try (
    java.util.zip.ZipFile zf =
         new java.util.zip.ZipFile(zipFileName);
    java.io.BufferedWriter writer = 
        java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) 
    // Enumerate each entry
    for (java.util.Enumeration entries =
                            zf.entries(); entries.hasMoreElements();) 
        // Get the entry name and write it to the output file
        String newLine = System.getProperty("line.separator");
        String zipEntryName =
             ((java.util.zip.ZipEntry)entries.nextElement()).getName() +
             newLine;
        writer.write(zipEntryName, 0, zipEntryName.length());
    

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

ResultSet 实现了AutoCloseable,这意味着 try-with-resources 也会在使用完毕时强制关闭它。

https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html

【讨论】:

以上是关于我应该在 try-with-resources 语句中声明每个资源吗?的主要内容,如果未能解决你的问题,请参考以下文章

我应该为每一行日志使用 try-with-resources 语句吗?

Java:我们应该尽快退出try-with-resource块来释放资源吗?

在 System.in 中使用 try-with-resources [重复]

如何为 java.util.logging.FileHandler 使用 try-with-resources?

android studio打开Zxing的android 项目出错,不支持try-with-resources?

在 Netbeans 中使用 try-with-resources