Java隐含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
语句中声明PreparedStatement
和ResultSet
。
既然你没有寻找内存泄漏,而是资源泄漏 。 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
将不会被关闭。