library
beginnertry-with-resources & AutoCloseable
Automatically close resources (streams, connections, locks) and avoid resource leaks using the try-with-resources statement.
Before Java 7, closing a resource correctly took a finally block that most people wrote slightly wrong. try-with-resources exists because the correct version is tedious and the incorrect version loses the original exception.
try-with-resources = a hotel checkout guarantee. You check into rooms (open resources) and the hotel guarantees checkout (close) even if you leave in a hurry (exception). If checkout itself fails, that problem is noted but doesn't prevent you from leaving.
Key Concepts
1
The mechanism. Anything implementing AutoCloseable can be declared in the parentheses of a try, and
the compiler generates the finally that closes it. Resources close in reverse order of declaration,
which matters when a later resource wraps an earlier one — a BufferedWriter around a FileWriter must
close first so its buffer flushes into a stream that is still open.
AutoCloseabletryfinallyBufferedWriterFileWriter
2
Suppressed exceptions are the detail that makes it better than hand-written code. If the body throws
and close() also throws, the body's exception propagates and the close exception is attached to it,
retrievable through getSuppressed(). The hand-written finally version does the opposite: the exception
from close() replaces the real failure, and the cause of the incident disappears. That inversion is why
this feature exists, and it is the answer interviewers are listening for.
close()getSuppressed()finally
3
Closeable versus AutoCloseable. Closeable came first, extends AutoCloseable, and declares
throws IOException; AutoCloseable declares throws Exception, so it fits non-IO resources such as
locks, database sessions and spans. Implement AutoCloseable for new types, and narrow the thrown type in
your override where you can.
CloseableAutoCloseablethrows IOExceptionthrows Exception
4
close() should be idempotent. try-with-resources calls it exactly once, but resources get closed by
other paths too — a pool returning a connection, a framework tearing down a context — and a second call
that throws turns cleanup into a new failure. Closeable explicitly requires that a repeat call has no
effect; make your implementations honour it.
close()Closeable
5
Java 9 removed the last piece of ceremony. An effectively final variable declared outside the try can
be used directly — try (conn) — instead of the Java 7 requirement to re-declare it as a new local. It is a
small change that removes the last reason people gave for not using the construct.
trytry (conn)
6
What the interviewer is probing.1. "What does try-with-resources do?" Probing: beyond "closes things". Stalls: "It's automatic
cleanup." Moves up: compiler-generated finally, reverse close order, and suppressed exceptions
preserving the original failure.
finally
7
2. "Body throws and close throws. What does the caller see?" Probing: the key behaviour. Stalls:
"The close exception." Moves up: the body's exception propagates; close's is attached as suppressed —
the opposite of the hand-written finally.
finally
8
3. "In what order do multiple resources close?" Probing: wrapping. Stalls: "In order." Moves up:
reverse of declaration, so a wrapper flushes into a stream that is still open.
9
4. "Closeable or AutoCloseable?" Probing: precision. Stalls: "They're the same." Moves up:
Closeable is the IO-specific ancestor throwing IOException; AutoCloseable is the general one
throwing Exception — use it for locks, sessions, spans.
CloseableIOExceptionAutoCloseableException
10
5. "Does close() run if the body returns early?" Probing: the guarantee. Stalls: "Only on
exception." Moves up: it runs on every exit — normal completion, return, break or throw.
11
Old finally versus try-with-resources12
// Java 6 -- close's exception REPLACES the real failure
InputStream in = null;
try {
in = new FileInputStream(f);
parse(in); // throws ParseException
} finally {
if (in != null) in.close(); // throws IOException
} // caller sees IOException,
// ParseException is gone13
// Java 7+ -- the real failure survives
try (InputStream in = new FileInputStream(f)) {
parse(in); // throws ParseException
} // caller sees ParseException;
// IOException is suppressed14
catch (ParseException e) {
for (Throwable s : e.getSuppressed()) { log(s); }
}15
Close order with wrapped resources16
try (FileWriter fw = new FileWriter(path);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(data);
}
// bw.close() runs FIRST (flushes into an open fw),
// then fw.close()
// Declaring them the other way round loses buffered data.17
Interface choice
Closeable extends AutoCloseable, throws IOException,
close() must be idempotent
AutoCloseable throws Exception; use for locks, transactions,
tracing spans, anything non-IO