Java隐式尝试资源

ski*_*iwi 15 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));
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

我完全理解rs将会被关闭,但也会PreparedStatement被关闭,如果是这样,原因是什么?因为ResultSet关闭还是因为尝试资源?

NIN*_*OOP 19

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

查看ResultSet#close()的javadoc :

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

然后是Statement#close():

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

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

ResultSet rs=conn.createStatement().executeQuery();
Run Code Online (Sandbox Code Playgroud)

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

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

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

看看从assylias这个答案,声明PreparedStatement以及ResultSet内部try声明.

既然你没有寻找内存泄漏,而是资源泄漏.的内存PreparedStatement最终将收集和它的内存被释放,因为它没有给它初始化的方式你的方法执行后不再提及,但是,资源持有的Statement未关闭.


ass*_*ias 9

你可以在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));
    }
}
Run Code Online (Sandbox Code Playgroud)