Try-with-resources: Must I throw or catch the close() method's exceptions? [duplicate]
Please correct me if this is wrong: In Java 7's try-with-resources statement, any exceptions thrown by the resource's close()
method must be either declared as thrown by my method or I must wrap the whole try in another try
which catches any exceptions thrown by close()
.
If so, I have to wonder if I will make much use of it. I certainly don't want to throw
the exceptions thrown by close()
, the caller won't know what to do with that. And a try
wrapping another try
just to handle close()
would not look very elegant, to me at least.
EDIT: I think I accidentally asked two questions, one of which was a duplicate.
Question 1. Do I have to declare that my method throws the exception from the close()
method or wrap the try-with-resources in another try? (Not answered in proposed duplicate.)
Question 2. Is there a way to close the resource silently? (Clearly a duplicate, so I am taking that sentence out of the question. Hopefully this makes the question satisfactorily unique.)
Solution 1:
Quote from Java Language Specification ($14.20.3.2):
14.20.3.2 Extended try-with-resources
A try-with-resources statement with at least one catch clause and/or a finally clause is called an extended try-with-resources statement. The meaning of an extended try-with-resources statement:
try ResourceSpecification
Block
Catchesopt
Finallyoptis given by the following translation to a basic try-with-resources statement (§14.20.3.1) nested inside a try-catch or try-finally or try-catch-finally statement:
try {
try ResourceSpecification
Block
}
Catchesopt
FinallyoptThe effect of the translation is to put the ResourceSpecification "inside" the try statement. This allows a catch clause of an extended try-with-resources statement to catch an exception due to the automatic initialization or closing of any resource.
So, basically, wrapper is already implemented
Solution 2:
From the Java tutorial
A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.
(emphasis mine)
So you can simply do
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
catch (IOException e) {
// handle the exception that has been thrown by readLine() OR by close().
}
Solution 3:
You do not need to wrap the try-with-resources in another try-catch block, you simply add a catch block:
class Foo implements AutoCloseable {
public void close() throws Exception {
throw new Exception();
}
}
public class Try {
public static void main(final String[] args) {
try(Foo f = new Foo()) {
System.out.println("No op!");
} catch(Exception e) {
e.printStackTrace();
}
}
}