I\'m wondering if putting a return statement inside a try-with-resources block prevents the resource to be automatically closed.
try(Connec
The resource will be closed automatically (even with a return
statement) since it implements the AutoCloseable
interface. Here is an example which outputs "closed successfully":
public class Main {
public static void main(String[] args) {
try (Foobar foobar = new Foobar()) {
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Foobar implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("closed successfully");
}
}
The AutoCloseable
interface can make the execution order of code confusing at first glance. Lets run through this with an example:
public class Main {
// An expensive resource which requires opening / closing
private static class Resource implements AutoCloseable {
public Resource() {
System.out.println("open");
}
@Override public void close() throws Exception {
System.out.println("close");
}
}
// find me a number!
private static int findNumber() {
// open the resource
try(Resource resource = new Resource()) {
// do some business logic (usually involving the resource) and return answer
return 2 + 2;
} catch(Exception e) {
// resource encountered a problem
throw new IllegalStateException(e);
}
}
public static void main(String[] args) {
System.out.println(findNumber());
}
}
The above code attempts to open some Resource
and conduct some business logic using the resource (just some arithmetic in this case). Running the code will print:
open
close
4
Therefore the Resource
is closed before exiting the try-with-resource block. To make it clear what exactly is going on, lets reorganise the findNumber()
method.
private static int findNumber() {
// open the resource
int number;
try(Resource resource = new Resource()) {
// do some business logic and return answer
number = 2 + 2;
} catch(Exception e) {
// resource encountered a problem
throw new IllegalStateException(e);
}
return number;
}
Conceptually, this is what happens under the hood when return
is placed inside a try-with-resource block. The return
operation is moved to after the try-with-resource block to allow the AutoCloseable
object to close before returning.
Therefore we can conclude that a return
operation inside a try-with-resource block is just syntactic sugar and you need not worry about returning before an AutoCloseable
has closed.
Based on Oracle's tutorial, "[the resource] will be closed regardless of whether the try statement completes normally or abruptly". It defines abruptly
as from an exception.
Returning inside the try
is an example of abrupt completion, as defined by JLS 14.1.