Reputation: 9776
I happened to realize, that this is the case. See this example below:
public class AutoClosableTest {
public static void main(String[] args) throws Exception {
try (MyClosable instance = new MyClosable()) {
if (true) {
System.out.println( "try" );
throw new Exception("Foo");
}
} catch( Exception e ) {
System.out.println( "Catched" );
} finally {
System.out.println( "Finally" );
}
}
public static class MyClosable implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println( "Closed." );
}
}
}
It prints:
try
Closed.
Catched
Finally
The try-with-resources is designed to avoid the messy finally sections with null checks and to avoid the leaked resources. Why are the resources closed BEFORE the catch section? What is the reason/idea/limitation behind it?
Upvotes: 20
Views: 3622
Reputation: 1074335
The answer can be found in JLS §14.20.3.2; the key parts are the last two paragraphs, particularly the last sentence of the penultimate paragraph (I've emphasized it):
A
try-with-resources
statement with at least onecatch
clause and/or afinally
clause is called an extendedtry-with-resources
statement.The meaning of an extended
try-with-resources
statement:try ResourceSpecification Block [Catches] [Finally]
is given by the following translation to a basic
try-with-resources
statement nested inside atry-catch
ortry-finally
ortry-catch-finally
statement:try { try ResourceSpecification Block } [Catches] [Finally]
The effect of the translation is to put the resource specification "inside" the
try
statement. This allows acatch
clause of an extendedtry-with-resources
statement to catch an exception due to the automatic initialization or closing of any resource.Furthermore, all resources will have been closed (or attempted to be closed) by the time the
finally
block is executed, in keeping with the intent of thefinally
keyword.
Upvotes: 15