关闭 AutoCloseable 的正确方法

Proper way to close an AutoCloseable

关闭 OutputStream, ServerSocket, or other object that implements the AutoCloseable 界面时最可靠的模式是什么?

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

即使抛出异常,使用 AutoCloseable instance is with a try-with-resources block, so the resource is reliably 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: that will misbehave for some edge cases (the cases that require a suppressed exception).

不要使用 shutdown-hook:资源很少真正是全局的,而且这种方法很容易出现竞争危险。 try-with-resources是推荐的正确关闭all的方式AutoCloseable资源:两者同时引入Java这样他们就可以一起工作了。

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

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