Quoting from the JLS section 14.20.3.1:
In a basic try-with-resources statement that manages a single resource:
This means that if both the code inside the try
block and the automatic close()
statement throw an exception, the catch
part will handle the exception thrown by the try
block, with the exception thrown by close()
in the suppressed exceptions.
Also, this means that if the try
block is successful but the automatic close()
fails, the catch
will sill be executed and the catched exception will be the exception thrown by close()
.
Here's a test to verify this behaviour:
public class Main {
public static void main(String[] args) throws Exception {
// try block fails and close() fails
try (T t = new T()) {
throw new Exception("thrown by try part");
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getSuppressed()[0].getMessage());
}
// try block is successful but close() fails
try (T t = new T()) {
//
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
class T implements AutoCloseable {
@Override
public void close() throws Exception {
throw new Exception("thrown by close");
}
}
This code will print
thrown by try part
thrown by close
thrown by close
meaning that the catched exception was the exception thrown by the try part of the code for the first part. For the second part, the catched exception was indeed the exception thrown by close()
.