繁体   English   中英

Java隐式尝试资源

[英]Java implicit try-with-resources

我想知道以下代码是否正确使用try-with-resources。

try (ResultSet rs = new QueryBuilder(connection, tableName(), getPaths(), searchQuery()).add(constraint).build().executeQuery()) {
    while (rs.next()) {
        beans.add(createBean(rs));
    }
}

争论并不重要,唯一重要的是:

  • new QueryBuilder().build(); 返回PreparedStatement

我完全理解rs会被关闭,但是PreparedStatement也会被关闭,如果是这样,出于什么原因? 因为ResultSet关闭还是因为try-with-resources?

PreparedStatement #close()将自动关闭任何关联的结果集,但反之则不正确,因为语句在结果集关闭后可重复使用。

查看ResultSet#close()的javadoc:

注意:当Statement对象关闭时,Statement对象会自动关闭,该对象会生成它

然后是Statement#close()

注意:关闭Statement对象时,其当前ResultSet对象(如果存在)也将关闭。

这个用法看起来很糟糕我:

ResultSet rs=conn.createStatement().executeQuery();

如果执行足够多次,它将泄漏所有可用游标,因为游标与Statement不与ResultSet相关联。

因此,要使用try-with-resources语句关闭底层PreparedStatement ,只需在try语句中声明它:

try-with-resources语句使用变量(称为资源)进行参数化,这些变量在执行try块之前初始化并自动关闭

从assylias这个答案 ,在try语句中声明PreparedStatementResultSet

既然你没有寻找内存泄漏,而是资源泄漏 PreparedStatement的内存最终将被收集并释放内存,因为在执行初始化方法后,它不再被引用,但是, Statement所持有的资源没有被关闭。

您可以在try中包含多个资源,它们都将被关闭 - 如果您希望关闭PreparedStatement ,这是必需的:

try (PreparedStatement ps = new QueryBuilder(connection, tableName(), getPaths(), searchQuery()).add(constraint).build();
        ResultSet rs = ps.executeQuery();) {
    while (rs.next()) {
        beans.add(createBean(rs));
    }
}

根据这里的文档- tryResourceClose ,正如我所读到的,它特定于declared资源。

The try-with-resources statement is a try statement that declares one or more resources.

进一步阅读你看到:

You may declare one or more resources in a try-with-resources statement. The following example retrieves the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files:

 try (
      java.util.zip.ZipFile zf =
         new java.util.zip.ZipFile(zipFileName);
    java.io.BufferedWriter writer = 
        java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
  ) {

我建议您正确答案的问题如下:

try{
  PreparedStatement statement = new QueryBuilder(connection, tableName(), getPaths(), searchQuery())
       .add(constraint).build();
  ResultSet rs = statement.executeQuery()) 
}

正如您所说, rs将被关闭。 这实际上意味着将在rs上调用close()方法。 因此,try-with-ressource语句在您的情况下不会明确地关闭PreparedStatement

如果它被关闭,否则(在rs.close()上下文中)在不知道实现的情况下很难说;-)

编辑

正如@TheNewIdiot正确找到的那样,您的PreparedStatement将不会被关闭。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM