在代码审阅期间,我发现以下代码段:
try (
Connection con = new SqlSessionFactoryBuilder()
.build(configuration)
.buildFactory()
.openSession()
.getConnection()
){
// do stuff here with 'con' and not close anything
}
session、connection、sqlsessionfactory都是ibatis实现,但问题在于可关闭接口的任何“堆叠”实现。
我假设“try with resources”关闭资源,在本例中是示例化的-con。通常,您会分别关闭会话和连接。如果使用上述代码,close()方法将只在con对象上调用,那么session不会显式调用,而是依赖于垃圾回收?
使用以下方法代码会更好:
try (
Session session = new SqlSessionFactoryBuilder()
.build(configuration)
.buildFactory()
.openSession();
Connection con = session.getConnection();
){
// do stuff here with 'con' and not close anything
}
在我看来,后一种方法似乎更干净,因为它应该正确地调用close()。或者我的解释是错误的,只是样板代码?
1条答案
按热度按时间mkshixfv1#
您的解释是正确的,try with resources将仅关闭resources块中显式声明的资源。
然而,在大多数情况下,第一种方法也会起作用。那是因为通常
Closeable
使用另一个Closeable
,它将尝试在其内部关闭它close()
方法。这个机制与垃圾收集器tho没有任何关系(它只是删除一个对象而不释放资源)。除了
Closeable
如果不关闭它的资源,那么在第一种方法中也可能有其他的资源泄漏源。考虑以下情况:在这个例子中,
FileInputStream
将首先创建。就在那时,它将成为一个BufferedInputStream
. 在创建过程中发生异常时会发生什么BufferedInputStream
?FileInputStream
永远不会关门。另一方面,当您将它们声明为两个独立的资源时,如下所示:java本身将确保关闭这两个资源。jsl-14.20.3.1中说明了以下内容。基本资源试用:
在管理多个资源的基本try with resources语句中:
如果资源的初始化由于抛出值v而突然完成,则:
如果所有成功初始化的资源(可能为零)的自动关闭正常完成,那么try with resources语句会因为抛出值v而突然完成。
可能还有更多的情况可能导致资源泄漏。