Destructor
Destructor

Reputation: 3284

What happens when with try resource when opening the resource throws exception?

I was working with try expression and I read the java documentation on this. https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html.

I understood that in case resource close and the code in try block both throw exception then the close exception is suppressed. But what happens in the case resource opening throws the exception? Do I need to catch it using a enclosed catch? How does this behave?

try (Statement stmt = con.createStatement()) {
        // use stmt here
}

Lets say creating statement threw an error, what happens now? Is it suppressed? I want to distinguish between this exception and any exception that might be thrown when the statement is created successfully and the block throws exception.

Thanks for the help!

Upvotes: 2

Views: 675

Answers (1)

Nicolas Filotto
Nicolas Filotto

Reputation: 44965

Lets say creating statement threw an error, what happens now? Is it suppressed?

No it is not suppressed, it is thrown as it is, indeed your code according to §14.20.3.1 of the Java Specification is equivalent to:

Throwable primaryExc = null;
Statement stmt = null;
try {
    stmt = con.createStatement();
    // use stmt here
} catch (Throwable e) {
    primaryExc = e;
    throw e;
} finally {
    if (stmt != null) {
        if (primaryExc != null) {
            try {
                stmt.close();
            } catch (Throwable ex) {
                primaryExc.addSuppressed(ex);
            }
        } else {
            stmt.close();
        }
    }
}

So as you can see if createStatement() throws an exception, if not caught explicitly the calling code will have to deal with this exception as a normal exception.

Please also note that like in the equivalent code snippet above if stmt.close() throws an exception while being called automatically by the try-with-resources statement, the calling code will have to deal with this exception as it won't be suppressed too.

The ability to suppress exceptions have been added for the try-with-resources statement to be able to get the exceptions that have been thrown while calling close() on resources when an exception has already been thrown in the try block, for example:

try (Statement stmt = con.createStatement()) {
    throw new RuntimeException("foo");
} catch (Exception e) {
    // Here e is my RuntimeException, if stmt.close() failed
    // I can get the related exception from e.getSuppressed()
}

Upvotes: 1

Related Questions