Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java try with resource是否可能无法关闭资源?_Java - Fatal编程技术网

Java try with resource是否可能无法关闭资源?

Java try with resource是否可能无法关闭资源?,java,Java,根据Oracle文档 try with resources语句是声明一个或多个资源的try语句。资源是一个对象,必须在程序完成后关闭。try with resources语句确保在语句末尾关闭每个资源。任何实现java.lang.AutoCloseable的对象(包括实现java.io.Closeable的所有对象)都可以用作资源 如果资源未实现AutoCloseable,则不能在try块中声明它,必须在主体部分中声明它&必须在finally块中显式关闭。 try-with-resource是否

根据Oracle文档

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

如果资源未实现AutoCloseable,则不能在try块中声明它,必须在主体部分中声明它&必须在finally块中显式关闭。 try-with-resource是否可能无法清理资源,除非您错误地使用习惯用法,例如存在嵌套资源&close()调用对于底层资源不是幂等的? 我的理解是try with resource只能确保close()在幕后被调用,但如果close本身不关闭底层资源,try with resource在清理资源时仍然无效。
是否有人有相反的观点或更多的澄清?

忽略实际不起作用的代码(例如您的示例中的
close()
方法没有实际关闭资源)或完全外部因素,例如人们将调试器连接到侧步清理,我可以想到三种情况,在这种情况下,try-with-resources可能无法清理资源:

  • 电源故障、硬件故障、操作系统崩溃或虚拟机崩溃。对于这类事情,没有什么软件可以做,所以它们不在资源处理的范围之内。但是,您仍然需要记住这一点,以防您考虑使用try-with-resources语句来管理诸如强制锁定文件之类的事情
  • 异步异常,例如由
    Thread.stop()
    生成的异常。如果线程在清理代码中以这种方式“停止”,则清理代码将中止。这种异步异常的不安全性就是为什么
    Thread.stop()
    被替换为
    Thread.interrupt()
    ,这是安全的
  • 如果调用了
    System.exit()
    。这可能被视为上述任何一种情况,但在“正常情况”下可能发生的情况除外

在所有其他方面,您应该能够放心,将调用
close()
。使用多个资源进行重试与嵌套的Try块相同,因此引发异常的清理代码不会停止其他清理例程。

忽略实际不起作用的代码(如您的示例中的
close()
方法没有实际关闭资源)或者完全是外部因素,比如人们将调试器附加到侧步清理上,我可以想到三种情况,在这种情况下,try-with-resources可能无法清理资源:

  • 电源故障、硬件故障、操作系统崩溃或虚拟机崩溃。对于这类事情,没有什么软件可以做,所以它们不在资源处理的范围之内。但是,您仍然需要记住这一点,以防您考虑使用try-with-resources语句来管理诸如强制锁定文件之类的事情
  • 异步异常,例如由
    Thread.stop()
    生成的异常。如果线程在清理代码中以这种方式“停止”,则清理代码将中止。这种异步异常的不安全性就是为什么
    Thread.stop()
    被替换为
    Thread.interrupt()
    ,这是安全的
  • 如果调用了
    System.exit()
    。这可能被视为上述任何一种情况,但在“正常情况”下可能发生的情况除外
在所有其他方面,您应该能够放心,将调用
close()
。使用多个资源重试与嵌套的Try块相同,因此引发异常的清理代码不会停止其他清理例程。

try (FileSystem fs = FileSystems.getDefault()) {
    return fs.getPath(aStringVar);
}
如果
FileSystems.getDefault()
返回一个
sun.nio.fs.UnixFileSystem
,就像它在使用Java 8 SE的RedHat机器上对我所做的那样,它将在关闭时抛出一个
UnsupportedOperationException
。尽管IntelliJ显示了警告并告诉您在使用资源进行尝试时包装这些警告,但您不应该这样做,除非您想处理那个愚蠢的异常。

是的

try (FileSystem fs = FileSystems.getDefault()) {
    return fs.getPath(aStringVar);
}

如果
FileSystems.getDefault()
返回一个
sun.nio.fs.UnixFileSystem
,就像它在使用Java 8 SE的RedHat机器上对我所做的那样,它将在关闭时抛出一个
UnsupportedOperationException
。尽管IntelliJ显示了警告并告诉您在使用资源进行尝试时将其包装,但您不应该这样做,除非您想处理那个愚蠢的异常。

您能为您认为可能出现故障的情况生成代码吗?这可能归结为“什么时候最后一个块不会运行”(这是非常罕见的,基本上只是在System.exit这样的情况下,它无论如何都不重要)还要注意的是,try-with-resources所做的一切都是调用
close
方法。如果该方法正确地完成了它的工作,那是另一个问题。我现在无法生成代码,我在日常编码中没有遇到这个问题,但在一次面试中有人问我&我告诉try-with-resource总是成功的,面试官不相信。你能吗您为您认为可能出现故障的情况生成代码?这可能归结为“最终块何时不运行”(这是非常罕见的,基本上只是System.exit之类的情况,在这种情况下它无论如何都不重要)还要注意的是,try-with-resources所做的一切都是调用
close
方法。如果该方法正确地完成了它的工作,那是另一个问题。我现在无法生成代码,我在日常编码中没有遇到这个问题,但在一次采访中有人问我&我告诉try-with-resource总是成功的,采访者对此并不信服。