Which two statements about the try-with-resources statement in Java 21 are correct? (Choose two.)
A. A resource variable declared in the resource specification is also in scope in the catch and finally clauses of the same try statement
Confuses lifetime with scope. A resource variable's scope is the resource specification and the try block only; naming it in catch or finally fails to compile with cannot find symbol, because by then the resource is already closed.
B. If a resource's close() is declared to throw a checked exception, the try-with-resources statement must catch that exception or the enclosing method must declare itCorrect answer
The implicit close() call is exception-checked like any other call, so a close() declared to throw a checked exception must be caught by the statement or declared by the enclosing method, otherwise javac reports an unreported exception.
C. An exception thrown by close() while the try body is already throwing is discarded, and only the body's exception is ever visible to the caller
Describes the pre-Java-7 finally idiom where the cleanup exception overwrote the real one. Try-with-resources keeps the body's exception primary and suppresses the close exception onto it, retrievable via getSuppressed(); nothing is lost.
D. A try-with-resources statement is legal with no catch clause and no finally clauseCorrect answer
The resource specification supplies the mandatory cleanup, so unlike a plain try (which needs a catch or a finally), a bare try (Res r = new Res()) { ... } compiles and runs, closing r on the way out.
Explanation
Why `If a resource's close() is declared to throw a checked exception, the try-with-resources statement must catch that exception or the enclosing method must declare it` is correct: the implicit call to `close()` is exception-checked like any other call. A resource whose `close()` is declared `throws IOException`, used in a try-with-resources with no matching catch and inside a `main` that declares no `throws`, is rejected by javac with `unreported exception IOException; must be caught or declared to be thrown` and the note `exception thrown from implicit call to close() on resource variable 'r'`. Add `catch (IOException e)` and the same program compiles and runs.
Why `A try-with-resources statement is legal with no catch clause and no finally clause` is correct: the resource specification supplies the mandatory cleanup, so unlike a plain `try` (which needs at least one catch or a finally), `try (Res r = new Res()) { ... }` on its own compiles and runs, closing `r` on the way out.
Why the others are wrong:
`A resource variable declared in the resource specification is also in scope in the catch and finally clauses...` confuses lifetime with scope. The resource variable's scope is the resource specification and the try *block* only; naming it in the finally clause fails to compile with `cannot find symbol`. This is deliberate — by the time catch or finally runs, the resource has already been closed, so reading it would be a bug.
`An exception thrown by close() while the try body is already throwing is discarded...` describes the pre-Java-7 finally idiom, where the cleanup exception overwrote the real one. Try-with-resources keeps the body's exception as primary and *suppresses* the close exception onto it; `getSuppressed()` returns it. Nothing is silently lost.
Exam tip: two resource-variable rules travel together — the variable is implicitly final, and its scope ends with the try block. And remember that a bare `try (…) { }` is the only form of `try` that needs neither catch nor finally.