Exceptions · ch. 8, p. 63
try-with-resources and suppressed exceptions
Any AutoCloseable declared in the try header is closed automatically, in reverse order, even on exception — and a failure during close is attached to the primary exception rather than replacing it.
try (InputStream in = Files.newInputStream(src);
OutputStream out = Files.newOutputStream(dst)) {
in.transferTo(out);
} // out closed first, then in — both guaranteed
What the old form got wrong
InputStream in = null;
try {
in = Files.newInputStream(src);
read(in); // throws IOException <- the real cause
} finally {
if (in != null) in.close(); // also throws <- this one wins
}
The exception from close() replaces the one you care about. try-with-resources
keeps the first and records the second:
catch (IOException e) {
for (Throwable s : e.getSuppressed()) { /* the close failure */ }
}
Details
- Resources must be effectively final; since Java 9 an existing final variable can be named directly in the header.
close()should be idempotent, because nothing prevents a second call.- A
finallyblock still runs after all resources are closed, if you need one.
2 questions on this concept Drill it