What are the requirements for resources in try-with-resources?
The resource must implement the java.lang.AutoCloseable interface. Without this, it cannot be used in try-with-resources.
Junior Level
Main requirement
The resource must implement the java.lang.AutoCloseable interface. Without this, it cannot be used in try-with-resources.
// Works - FileInputStream implements AutoCloseable
try (FileInputStream fis = new FileInputStream("file.txt")) {
fis.read();
}
// Won't compile - String does not implement AutoCloseable
try (String s = "hello") { } // Compilation error
Which classes implement AutoCloseable
- All
InputStream/OutputStream- files, network - All
Reader/Writer- text Connection,Statement,ResultSet- databaseScanner,Formatter- utilities
Multiple resources
try (FileInputStream fis = new FileInputStream("in.txt");
FileOutputStream fos = new FileOutputStream("out.txt")) {
// Both will be closed automatically
}
Java 9+ - external variables
FileInputStream fis = createStream();
try (fis) { // fis must be effectively final
fis.read();
}
When NOT to put resource in try-with-resources
- Container-managed resource (Spring @Bean) - framework closes it itself
- Pooled connection (HikariCP) - pool manages lifecycle for you
- Need to pass resource further - return from method, TWR will close before return
Middle Level
AutoCloseable vs Closeable
AutoCloseable (Java 7, java.lang):
void close() throws Exception- Universal - for any resources
Closeable (Java 5, java.io):
void close() throws IOException- Only for I/O
- Inherits
AutoCloseable
Either one works for try-with-resources.
Leak risk during initialization
// SAFE - if B fails, A will close
try (A a = new A(); B b = new B(a)) { }
// DANGEROUS - if B fails, A leaks
try (B b = new B(new A())) { }
// A is created but try has no reference to it
// Leak analysis: new A() created object. new B(a) threw exception.
// A is created, but the variable in TWR is B. TWR has no reference to A,
// so close() for A won't be called. Solution:
// try (A a = new A(); B b = new B(a)) { ... }
Idempotency of close()
The close() method must be idempotent - repeated call should not throw an exception.
Idempotency - property of an operation: repeated call produces the same result as the first. close() must be idempotent: first call closes resource, second - does nothing (doesn’t throw).
public void close() {
if (closed.compareAndSet(false, true)) {
// actual resource release
}
}
Variable requirements (Java 9+)
Resource must be final or effectively final. Compiler creates a local copy of the reference - this guarantees that if another thread changes the external variable, TWR still closes the original object.
effectively final = variable doesn’t change after initialization, even if the final keyword is not written. The compiler sees that you don’t change the variable and allows using it in TWR.
Senior Level
Under the Hood: compiler creates a copy
When using an external variable in try(resource), the compiler creates a local copy of the reference. This guarantees thread-safe closing.
Throwing exceptions from close()
If close() throws an exception:
- If there were no errors in
try- exception fromclose()becomes the main one - If there was already an exception in
try- fromclose()is added tosuppressed
Interrupted close
In network operations, close() may block. Set timeouts, otherwise the thread will “hang” at the resource closing stage.
Object Allocation and GC
try-with-resources creates objects. When opening/closing thousands of resources per second, this creates pressure on GC (Young Generation). Use resource pools (HikariCP for DB), which implement AutoCloseable but instead of closing, return the object to the pool.
Edge Cases
- Resource didn’t open - if constructor threw, TWR won’t try to close (nothing to close)
- Partial initialization - if constructor opened native resource but failed before returning - leak. Keep constructors light.
Diagnostics
- Resource Leak Detection - IDE highlights
AutoCloseableclasses not used in TWR. Don’t ignore. jstackanalysis - many threads inBLOCKED/WAITINGinclose()- check for deadlocks between resources.
Interview Cheat Sheet
Must know:
- Resource must implement
java.lang.AutoCloseable AutoCloseable(Java 7,java.lang) -close() throws Exception;Closeable(Java 5,java.io) -close() throws IOExceptionclose()method must be idempotent - repeated call doesn’t throw- Declare resources separately:
try (A a = new A(); B b = new B(a))- otherwise leak - Java 9+: external variables must be
effectively final - Compiler creates local copy of reference - guarantees thread-safe closing
- If
close()throws when there’s an error intry- added tosuppressed - Resource pools (HikariCP) implement AutoCloseable but return object to pool, not close
Frequent follow-up questions:
- What is the difference between AutoCloseable and Closeable? - AutoCloseable is more universal (throws Exception), Closeable only for I/O (throws IOException)
- What is idempotency of close()? - First call closes resource, second - does nothing
- Why is nested resource creation dangerous? -
new B(new A())- if B fails, TWR has no reference to A, it leaks - What happens on mass open/close of resources? - GC pressure; use resource pools
Red flags (NOT to say):
- “Close() can throw exception every time” - must be idempotent
- “I don’t declare resources separately to make it shorter” - this causes leaks
- “TWR closes pooled connection” - pool manages lifecycle itself, return != close
Related topics:
- [[What is try-with-resources]]
- [[What is the AutoCloseable interface]]
- [[What is the difference between AutoCloseable and Closeable]]
- [[What are suppressed exceptions]]
- [[Which exceptions must be handled]]