In the following block of code:
try ( /* resources declaration */ ) {
// some dangerous code
} catch (Exception e) {
// error handling and reporting
}
What would happen if both the code inside the try
block and the automatic close()
statement threw exceptions? Which one would get caught in the catch
block? Both of them? Only one of them? If so, which one?
Furthermore, what if the try
is successful but the close
is not? Would the catch block be entered?
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. Any object that implements java.
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.
This the catch is optional because readLine() doesn't throw a (checked) exception. Yes, close() could throw an exception, but the try-with-resources handles that too. So this try-with-resources doesn't need a catch.
The try-with-resources statement is a try statement with one or more resources duly declared. Here resource is an object which should be closed once it is no more required. The try-with-resources statement ensures that each resource is closed after the requirement finishes.
Quoting from the JLS section 14.20.3.1:
In a basic try-with-resources statement that manages a single resource:
- If the initialization of the resource completes abruptly because of a
throw
of a valueV
, then the try-with-resources statement completes abruptly because of athrow
of the valueV
.If the initialization of the resource completes normally, and the
try
block completes abruptly because of athrow
of a valueV
, then:
If the automatic closing of the resource completes normally, then the try-with-resources statement completes abruptly because of a
throw
of the valueV
.If the automatic closing of the resource completes abruptly because of a
throw
of a valueV2
, then the try-with-resources statement completes abruptly because of athrow
of valueV
withV2
added to the suppressed exception list ofV
.- If the initialization of the resource completes normally, and the
try
block completes normally, and the automatic closing of the resource completes abruptly because of a throw of a valueV
, then the try-with-resources statement completes abruptly because of athrow
of the valueV
.
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()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With