根据Oracle文档
try-with-resources语句是一个声明一个或多个资源的try语句。资源是一个对象,必须在程序完成后关闭它。 try-with-resources语句确保在语句结束时关闭每个资源。实现java.lang.AutoCloseable的任何对象(包括实现java.io.Closeable的所有对象)都可以用作资源
如果资源没有实现AutoCloseable,则无法在try块中声明它,它必须在body部分中声明。必须在finally块中显式关闭。 try-with-resource是否有可能无法清理资源,除非您使用不正确的习惯用法,如果有嵌套资源& close()调用对底层资源不是幂等的? 我所理解的是try-with-resource只能确保在场景后面调用close(),但如果close本身不关闭底层资源,try-with-resource将无法清理资源。 有没有人有相反的观点或更多的澄清?
答案 0 :(得分:1)
忽略实际上不起作用的代码(比如你的close()
方法没有实际关闭资源的例子)或者人们将调试器附加到边步清理这样的完全外部因素,我可以想到三种情况try-with-resources可能无法清理资源:
Thread.stop()
生成的异常。如果在清理代码中以这种方式“停止”某个线程,则清除代码将被中止。此类异步异常的不安全性是Thread.stop()
为deprecated并替换为Thread.interrupt()
的原因,这是安全的。System.exit()
。这可能被认为是上述任何一种情况,除非它可能在“正常情况下”发生。在所有其他方面,您应该能够放心,close()
将被召唤。尝试使用多个资源与嵌套的try块相同,因此抛出异常的清理代码不会阻止其他清理例程。
答案 1 :(得分:0)
是
try (FileSystem fs = FileSystems.getDefault()) {
return fs.getPath(aStringVar);
}
如果FileSystems.getDefault()
返回sun.nio.fs.UnixFileSystem
,就像在使用Java 8 SE的RedHat机器上为我做的那样,它会在关闭时抛出UnsupportedOperationException
。尽管IntelliJ显示警告并告诉你将其包装在try-with-resources中,但你不应该这样做,除非你想处理那个愚蠢的例外。