Why is close() method of the resource called before catch in a try-with-resources construct in Java?
Asked Answered
N

1

20

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

Question

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?

Nordgren answered 31/7, 2014 at 10:59 Comment(0)
W
15

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 one catch clause and/or a finally clause is called an extended try-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 a try-catch or try-finally or try-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 a catch clause of an extended try-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 the finally keyword.

Worden answered 31/7, 2014 at 11:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.