关闭 AutoCloseable 的正确方法

Posted

技术标签:

【中文标题】关闭 AutoCloseable 的正确方法【英文标题】:Proper way to close an AutoCloseable 【发布时间】:2019-05-13 12:41:20 【问题描述】:

关闭OutputStreamServerSocket 或其他实现AutoCloseable 接口的对象时,最可靠的模式是什么?

我应该使用try-catch-finally吗?或关闭挂钩。

【问题讨论】:

我正在回答我自己的问题as is encouraged。 【参考方案1】:

使用AutoCloseable 实例的正确方法是使用try-with-resources 块,因此即使抛出异常,资源也是可靠的closed。

像这样:

    try (OutputStream stream = new ...) 
       ... // use the resource
     catch (IOException e) 
        ... // exception handling code
    

您也可以control multiple resources 使用一个块(而不是嵌套块):

try (
     OutputStream out1 = ...;
     OutputStream out2 = ...;
     InputStream in1 = ...;
     InputStream in2 = ...;
) 
     ...

Don't use a try...finally block:对于某些边缘情况(需要suppressed exception 的情况),这将是错误的。

不要使用关闭挂钩:资源很少是真正全局的,这种方法很容易出现竞争风险。 try-with-resources 是正确关闭all AutoCloseable 资源的推荐方式:这两者是同时引入Java的,因此它们可以一起工作。

隐含地这样做有助于实现(推荐的)规则,即只有负责创建或打开某物的代码才负责处置或关闭它:如果一个方法被传递一个OutputStream,它应该从不close()它。相反,它应该依赖于调用者关闭它。如果您的任何方法都没有显式调用close(),则保证您的代码永远不会抛出异常(例如"Socket closed" java.net.SocketException),因为它会尝试使用已关闭的资源。

这样做可以确保资源准确地关闭一次。请注意,通常多次关闭 AutoCloseable 是不安全的:close() 操作保证是幂等的。

【讨论】:

你为什么要回答自己的问题? @Rick 我正在回答我自己的问题as is encouraged。您应该阅读游览

以上是关于关闭 AutoCloseable 的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

源码分析-AutoCloseable

try(){}自动释放资源,AutoCloseable

浅谈JAVA中的AutoCloseable接口

浅谈JAVA中的AutoCloseable接口

AutoCloseable close() 方法异常没有被抑制

AutoCloseable.close() 方法是不是破坏了 Java 的向后兼容规则