What is the difference between AutoCloseable and Closeable?
Closeable is a special case of AutoCloseable only for I/O operations.
Junior Level
Short answer
Closeable is a special case of AutoCloseable only for I/O operations.
AutoCloseable (java.lang)
└── Closeable (java.io)
└── FileInputStream, BufferedReader, etc.
Key differences
| Characteristic | Closeable | AutoCloseable |
|---|---|---|
| Package | java.io |
java.lang |
| Exception | throws IOException |
throws Exception |
| Purpose | I/O only | Any resources |
Examples
// Closeable - only I/O
try (FileInputStream fis = new FileInputStream("file.txt")) {
fis.read();
} // close() throws IOException
// AutoCloseable - any resource
try (Connection conn = dataSource.getConnection()) {
conn.createStatement().executeQuery("SELECT 1");
} // close() throws SQLException
Which to use
- For files, streams -
Closeable(already implemented in JDK) - For custom resources (DB, transactions) -
AutoCloseable
Middle Level
Hierarchy (since Java 7)
Closeable inherits AutoCloseable. This was done for backward compatibility - all old I/O classes work in try-with-resources.
Contract differences
Idempotency:
Closeable- Javadoc requires idempotency: “if already closed, call has no effect”AutoCloseable- Javadoc recommends: “strongly recommended…”- In practice, both should be idempotent.
Reason: some resources (transactions) may throw an exception when trying to close an already closed transaction.
Flushable & Closeable
Many Closeable classes also implement Flushable:
Flushable - interface with flush() method. Flush = flush buffered data. BufferedOutputStream.close() first calls flush() to write buffered data to disk.
public class BufferedOutputStream extends FilterOutputStream
implements Flushable, Closeable {
public void close() throws IOException {
flush(); // Flushes buffer before closing
out.close();
}
}
On close, close() typically calls flush(). But this depends on implementation.
Exception Narrowing
When implementing AutoCloseable for your services, remove throws Exception:
// Bad
public class MyService implements AutoCloseable {
public void close() throws Exception { }
}
// Good
public class MyService implements AutoCloseable {
public void close() { } // No throws - clean and safe
}
What to implement in your class
- Closeable - if your class is an I/O stream (works with bytes/characters)
- AutoCloseable - if your class is any other resource (DB connection, transaction, lock)
Senior Level
Suppressed Exceptions Priority
When closing several resources in TWR, order - LIFO (Last In, First Out). Exception from the most inner resource is added last to the suppressed list.
// When closing A, B, C (in this order), if all three fail: // A - main exception // B and C - suppressed (order: B then C, LIFO)
Interrupted Close
If close() is blocking (closing network pool) and thread is interrupted - InterruptedException. TWR doesn’t magically handle interrupts - you still need catch.
Static Analysis
instanceof Closeable also means instanceof AutoCloseable. But not vice versa!
Edge Cases
- Transactional resources -
close()may mean “commit”. Repeated call must be safe - Shared resources - if resource is used by multiple components, closing one must not break others
Diagnostics
In Highload systems, file descriptor leak due to wrong choice between these interfaces in custom wrappers - one of the most common causes of JVM crash after several days of operation.
lsof -p <pid>- shows open file descriptorsjstack- shows blocked threads inclose()- Metrics - track number of open connections via Micrometer
Interview Cheat Sheet
Must know:
Closeableinherits fromAutoCloseable(hierarchy:AutoCloseable<-Closeable)Closeableinjava.io, throwsIOException;AutoCloseableinjava.lang, throwsExceptionCloseable- only for I/O streams;AutoCloseable- for any resources (DB, transactions, locks)- Both should be idempotent, but for
Closeableit’s a strict Javadoc requirement - When implementing, narrow exception type or remove
throwscompletely - Close order in TWR - LIFO (last opened closed first)
Frequent follow-up questions:
- Which interface to implement in your class? -
Closeableif it’s an I/O stream,AutoCloseablefor everything else - What is Exception Narrowing? - When implementing
AutoCloseable, replacethrows Exceptionwith specific type or remove - Why does
CloseablethrowIOException? - Historically: created for I/O operations, whereIOExceptionis the only expected error - What happens if you close a shared resource from two components? - Second call must be safe (idempotency); otherwise - architecture bug
Red flags (NOT to say):
- “They are the same” - Different packages, contracts, and purposes
- “AutoCloseable throws only RuntimeException” - Throws
Exception(checked), but you can narrow - “Close order doesn’t matter” - LIFO is critical: outermost resource closes last
Related topics:
- [[11. What is the AutoCloseable interface]]
- [[9. What is try-with-resources]]
- [[10. What are the requirements for resources in try-with-resources]]
- [[23. What are suppressed exceptions]]
- [[18. What is exception wrapping (wrapping)]]