Java 是否应该从终结器关闭ResultSet调用的自动关闭迭代器?

Java 是否应该从终结器关闭ResultSet调用的自动关闭迭代器?,java,iterator,resultset,finalizer,autocloseable,Java,Iterator,Resultset,Finalizer,Autocloseable,我有一个由结果集支持的迭代器。我需要它来进行行级后处理。迭代器实现自动关闭接口。 连接保持打开状态,直到我们遍历所有被用户中断的行/迭代。如果迭代器的使用者显式调用close()方法,或者将迭代器的使用包装在Java7 try块中,那么一切都很好。但是,如果使用者不这样做,我不能保证连接将返回到池中。在C#world中,我们将使用终结器并从终结器调用Dispose(bool)作为回退选项。我们应该在Java中也这样做吗?这种清理通常不是在Javafinalize()方法中完成的。未能确保正确处置

我有一个由结果集支持的迭代器。我需要它来进行行级后处理。迭代器实现自动关闭接口。
连接保持打开状态,直到我们遍历所有被用户中断的行/迭代。如果迭代器的使用者显式调用close()方法,或者将迭代器的使用包装在Java7 try块中,那么一切都很好。但是,如果使用者不这样做,我不能保证连接将返回到池中。在C#world中,我们将使用终结器并从终结器调用Dispose(bool)作为回退选项。我们应该在Java中也这样做吗?

这种清理通常不是在Java
finalize()方法中完成的。未能确保正确处置资源是编程错误;试图在糟糕的编程之后进行清理是让糟糕的做法得以延续

更常见的是一个调试选项,用于帮助那些承认自己有问题的开发人员。由于涉及的开销,默认情况下通常不启用此功能,但当启用right标志时,将在分配资源时创建堆栈跟踪。如果调用
finalize()
时未正确销毁资源,则会记录堆栈以显示泄漏的位置


关于
finalize()
,有许多警告,您通常应该避免使用它。本例中的一个主要问题是,无法保证它会被调用,即使被调用,也可能没有及时提供帮助。

否。如果您的
迭代器超出范围,那么
结果集也会被调用。因此,让
ResultSet
的维护者(例如JDBC驱动程序实现者)决定是否跟踪
ResultSet
实例。这不是您的
迭代器的责任。我确实理解终结过程中的陷阱,例如延长对象的TTL等等。然而,这种类型的bug(非托管资源管理)让我们面临资源泄漏,不是吗?在没有任何保证的情况下,我们还是应该把婴儿和洗澡水一起扔掉?我的意思是这个bug很难被发现。只有在特定负载下,当您从池中获得的连接数量受到某种限制,或者数据库不允许显式地创建更多的连接时,才可以使用。您的评论是否仍然适用?如果不了解您是如何使用此
迭代器的,很难说它是否适用。我可以理解,您可能需要将
结果集
改编为
迭代器
,以便将其传递给无法修改的第三方API;但是我不明白为什么在调用第三方API返回后,执行这种自适应的代码不能可靠地显式地调用底层的
ResultSet
。Erickson是对的:如果没有调用
close()
,这是消费者的错,对此你无能为力。您最好按照Erickson的建议使用终结器检查资源是否已关闭,并记录一条警告,在这种情况下让开发人员知道泄漏。