Try-With-Resources with Existing Variables
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
A try-with-resources statement does not always need to declare a new variable. Since Java 9, its resource list may directly reference an existing final or effectively-final local variable or parameter. BufferedReader reader = ...; try (reader) { ... } is therefore valid when reader is assigned once and never reassigned.
Effectively final means the compiler can treat the reference as fixed even though the final keyword is absent. If code later assigns a different reader to the variable, it no longer qualifies and the try header does not compile. The restriction ensures that Java knows exactly which object is owned by that resource entry.
The statement still closes the resource at the end. The variable's lexical scope may continue afterward, but using it is normally invalid because the underlying reader, stream, or connection is closed. Existing-variable syntax is about avoiding an unnecessary alias, not extending resource lifetime.
For example, a method may receive an effectively-final BufferedReader from earlier setup, enter try (reader), read its first line, and return. Java closes it before the return completes. This is concise when ownership has clearly transferred to the method or block.
Ownership must not be inferred only from the syntax. If a framework, caller, or shared component expects to keep using the object, placing it in try-with-resources is a bug even when the compiler accepts it. Use an existing resource variable when the close responsibility is explicit, keep the closing scope small, and remember that compatibility with Java 8 source requires the older declaration form or a new alias.
Try-With-Resources with Existing Variables
Direct Answer
Since Java 9, a try-with-resources header may reference an existing final or effectively-final local variable or parameter directly. It need not redeclare the variable, but the reference must not be reassigned and the statement still closes that resource.
Deep Dive & Architecture
The compiler needs a stable resource reference so that the object used in the body is the one closed at exit. A final variable states that stability directly. An effectively-final variable achieves the same result through data flow: it receives one assignment and is never the target of another assignment.
Java 9's enhancement removed a common Java 7 duplication. Earlier code often wrote Resource original = acquire(); try (Resource alias = original). The alias existed only to satisfy the declaration grammar. The newer try (original) form preserves the same close semantics without introducing a second name.
The variable and object lifetime remain different. After the block, the local variable may still be visible, but it references an object whose close method has run. APIs should make post-close behavior clear; many streams throw IOException, while a custom object may throw IllegalStateException or define harmless inspection methods.
Parameters can also be effectively final and appear in a resource list. That does not automatically grant ownership. A method that closes a parameter should state the transfer in its contract, because Java conventions often leave caller-supplied resource ownership with the caller. Compiler validity and API design are separate questions.
Code Example
import java.io.BufferedReader;
import java.io.StringReader;
class ExistingResourceVariable {
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new StringReader("first\nsecond"));
String line;
try (reader) {
line = reader.readLine();
}
if (!"first".equals(line)) throw new AssertionError(line);
try {
reader.readLine();
throw new AssertionError("reader should be closed");
} catch (java.io.IOException expected) {
System.out.println(line + ":closed");
}
}
}
Check your understanding
Answer these without looking back at the article.
- What makes a local variable effectively final?
- Does the resource remain open because its variable is still in scope?
- Why can a caller-supplied AutoCloseable still be wrong to close?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.