Proper way to close an AutoCloseable
What is the most reliable pattern to follow when closing an OutputStream
, ServerSocket
, or other object that implements the AutoCloseable
interface?
Should I use try
-catch
-finally
? Or a shutdown hook.
The correct way to use an AutoCloseable
instance is with a try
-with-resources block, so the resource is reliably closed even if an exception is thrown.
Like this:
try (OutputStream stream = new ...) {
... // use the resource
} catch (IOException e) {
... // exception handling code
}
You can also control multiple resources using one block (rather than nested blocks):
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).
Don't use a shutdown-hook: resources are rarely truely gloabl, and that approach will be prone to race hazards. try
-with-resources is the recommended manner of properly closing all AutoCloseable
resources: the two were introduced to Java at the same time so they can work together.
Doing this implicitly helps implement the (recommended) rule that only the code responsible for creating or opening something is responsible for disposing or closing it: if a method is passed an OutputStream
, it should never close()
it. It should instead rely on the caller closing it. If none of your methods explicitly call close()
, your code is guaranteed never to throw an exception (such as a "Socket closed" java.net.SocketException
) because it attempts to use a resource that has been closed.
Doing this ensures that the resource is closed precisely once. Beware that in general it is unsafe to close an AutoCloseable
more than once: the close()
operation is not guaranteed to be idempotent.