试用资源是否可能无法关闭资源?

问题描述:

按照Oracle文档试用资源是否可能无法关闭资源?

try-with-resources语句是声明一个或多个资源的try语句。资源是一个对象,在程序结束后必须关闭。 try-with-resources语句确保每个资源在语句结束时都关闭。实现java.lang.AutoCloseable的任何对象,包括实现java.io.Closeable所有对象,可以用来作为资源

如果资源没有实现AutoCloseable不能try块内声明的,必须在正文部分&中声明必须在finally块中明确关闭。 是否有可能尝试与资源无法清理资源,除非像使用嵌套资源那样错误地使用习语& close()调用对于底层资源不是幂等的吗? 我的理解是try-with-resource只能确保close()在场景后面被调用,但如果关闭本身并没有关闭底层资源,那么尝试使用资源对于清理资源仍然不起作用。 有没有人有相反的观点或更多的澄清?

+1

您是否可以为您认为可能出现故障的情况生成代码? – djechlin

+0

这可能归结为“什么时候终止块不能运行”(这是非常罕见的,基本上只是像System.exit那样它应该无关紧要的情况)? – Thilo

+2

另请注意,所有试用资源都是调用'close'方法。如果该方法正确地完成其工作是另一个问题。 – Thilo

无视实际上不起作用的代码(就像您的close()方法没有真正关闭资源的示例),或者是将调试器附加到边清理的完全外部因素,我可以想到三种情况:try-with - 资源可能无法清除资源:

  • 电源故障,硬件故障,操作系统崩溃或虚拟机崩溃。对于这样的事情,软件可以做的不多,所以它们超出了资源处理的范围。但是,如果您想要管理诸如强制锁定文件之类的事情,以及尝试使用资源语句时,仍需记住这一点。
  • 异步例外,例如由Thread.stop()生成的例外。如果一个线程在清理代码时以这种方式“停止”,那么清理代码将被中止。这种异步例外的不安全性是为什么Thread.stop()deprecated并且替换为Thread.interrupt(),这是安全的。
  • 如果调用System.exit()。这可能被认为是上述任何一种情况,只不过它可能发生在“正常情况下”。

在所有其他方面,您应该能够放心,close()将被称为。 Try-with-several-resources与嵌套try块相同,因此清理代码抛出异常不会停止其他清理例程。