AutoCloseable Interface and Try-With-Resources
Fast recall
Quick revision
Core answer
AutoCloseable declares void close() throws Exception; an object assignable to it can be managed by try-with-resources. Closeable extends it and narrows the declared failure to IOException. AutoCloseable does not require close() to be idempotent, although idempotence is often a useful class-specific design; callers must follow the resource's documented lifecycle.Whether you know AutoCloseable is the contract behind try-with-resources and can implement it on a custom class
Confusing Closeable and AutoCloseable, or thinking only JDK classes can be used in try-with-resources
Note Closeable extends AutoCloseable and predates it (Java 5 vs 7), and that repeated-close behavior should follow the concrete contract
Interview-ready guide
Interview answer
AutoCloseable is the contract used by try-with-resources. It declares close(), which may throw Exception. Closeable is an I/O-focused subinterface that narrows the declared failure to IOException and specifies that closing an already closed stream has no effect. AutoCloseable itself does not require repeated close calls to be harmless, although an implementation may make them so.
For example, try (BufferedReader reader = Files.newBufferedReader(path)) { ... } works because the reader is Closeable, and Java calls reader.close() when the block ends whether the body completes normally or throws. A database transaction scope could implement AutoCloseable with a different checked-failure contract. I therefore program to the documented lifecycle of the concrete resource and let its close() method declare a narrower exception when possible.
AutoCloseable Interface and Try-With-Resources
Direct Answer
AutoCloseable declares void close() throws Exception; an object assignable to it can be managed by try-with-resources. Closeable extends it and narrows the declared failure to IOException. AutoCloseable does not require close() to be idempotent, although idempotence is often a useful class-specific design; callers must follow the resource's documented lifecycle.
Code Example
Implement AutoCloseable, put cleanup in close(), and the resource works in any try header.
public class DbConnection implements AutoCloseable {
DbConnection() { System.out.println("opened"); }
void query(String sql) { System.out.println("run: " + sql); }
@Override
public void close() { // narrowed: declares no checked exception
System.out.println("closed"); // release the underlying resource here
}
}
// Usage -- close() runs automatically, even if query() throws:
try (DbConnection db = new DbConnection()) {
db.query("SELECT 1");
}
// prints: opened, run: SELECT 1, closed
Common Mistakes & Pitfalls
- Confusing the direction:
CloseableextendsAutoCloseable, not the other way around. - Thinking only JDK resources qualify: any assignable implementation can appear in the resource list.
- Assuming every
close()is idempotent:Closeablerequires harmless repeat close, whileAutoCloseabledoes not. - Calling close manually inside the try: this can cause a second close with implementation-specific behavior.
- Declaring
throws Exceptionunnecessarily: an implementation may narrow the checked type or declare none.
Check your understanding
Answer these without looking back at the article.
- What is the difference between AutoCloseable and Closeable?
- How do you make a custom class work with try-with-resources?
- Does close() in try-with-resources get called even if an exception is thrown?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.