Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the close method on a try-with-resources idiom not called if a constructor throws an exception?

I have a base class Base and a child class Child which extends it. Base implements java.lang.AutoCloseable.

Let's suppose that the constructor for Child throws a Foo.

Now consider

try (Base c = new Child()){
    /*Some code*/
} catch (final Foo e){
    /*Some more code*/
}

Is the Base#close method called if the exception is thrown? It is not on my machine, but is this something that the JLS has standardised?

like image 795
P45 Imminent Avatar asked Jan 08 '16 13:01

P45 Imminent


People also ask

Does throwing an exception exit the method?

When an exception is thrown the method stops execution right after the "throw" statement. Any statements following the "throw" statement are not executed.

What is the difference between try and try-with-resources?

The try -with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try -with-resources statement ensures that each resource is closed at the end of the statement.

How do you handle exceptions in trying with resources?

For try-with-resources, if an exception is thrown in a try block and in a try-with-resources statement, then the method returns the exception thrown in the try block. The exceptions thrown by try-with-resources are suppressed, i.e. we can say that try-with-resources block throws suppressed exceptions.

What is try () in Java?

The try statement allows you to define a block of code to be tested for errors while it is being executed. The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.


2 Answers

Yes, close won't be called. This is specified in the JLS section 14.20.3:

Resources are initialized in left-to-right order. If a resource fails to initialize (that is, its initializer expression throws an exception), then all resources initialized so far by the try-with-resources statement are closed. If all resources initialize successfully, the try block executes as normal and then all non-null resources of the try-with-resources statement are closed.

Resources are closed in the reverse order from that in which they were initialized. A resource is closed only if it initialized to a non-null value. An exception from the closing of one resource does not prevent the closing of other resources. Such an exception is suppressed if an exception was thrown previously by an initializer, the try block, or the closing of a resource.

In this case, an exception is thrown in the constructor so the resource is not initialized to a non-null value. Hence, the close method isn't called.

like image 132
Tunaki Avatar answered Oct 05 '22 02:10

Tunaki


close will not be called. It wouldn't make sense to call it, since you don't have a fully-constructed object to close, and in similar calls, you might not have even entered a constructor:

try (Base b = makeBase()) {
    ...
}

where makeBase is

Base makeBase() {
    throw new RuntimeException();
}
like image 43
user2357112 supports Monica Avatar answered Oct 05 '22 00:10

user2357112 supports Monica