Reputation: 37034
interface AutoClosable
has following method declaration:
void close() throws Exception
Thus we see that method close can throws Exception.
When I write code try-with resources it is looks like this:
private static void printFileJava7() throws IOException {
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
}
}
At this code is absent Exception handling.
I don't understand what happens if close method throws exception.
Upvotes: 0
Views: 521
Reputation: 147
You need to have a catch block followed by try in the method printFileJava7(). If you don't want to catch it here, you need handle it in the method which calls the method printFileJava7(). We have to catch in one of the layers otherwise it will be propagated back to the calling client.
Upvotes: 0
Reputation: 1867
The key to this particular scenario is the "supressed exception".
"Whenever an exception is thrown within the body, and then followed by an exception thrown by the try-with-resources statement, only the exception thrown in the body of the try is eligible to be caught by the exception handling code. All other exceptions are considered supressed exceptions"
A concept that is new with Java 7.SO you will get the same output as when only the printfileJava7 class throws an exception, since the CloseException thrown by the close() method would be suppressed.
Please refer to When two exceptions are thrown by the try-with-resources construct link.Which have taken exact scenario what You have asked
Upvotes: 0
Reputation: 17595
From the jls about Compile-Time Checking of Exceptions
When interfaces are involved, more than one method declaration may be overridden by a single overriding declaration. In this case, the overriding declaration must have a throws clause that is compatible with all the overridden declarations (§9.4.1).
So when you have something like
static class AC implements AutoCloseable {
@Override
public void close() throws Exception {
throw new Exception("btooom!");
}
public void ac() {
System.out.println("no");
}
}
public static void main(String[] args) throws Exception {
try(AC ac = new AC()) {
ac.ac();
}
}
then you are forded to either add a catch clause to the surrounding try block or add a throws declaration.
In the case of FileInputStream and to apply what the jsl states, the AutoCloseable's close method is overriden from Closeable's, hence you only have to catch an IOException or add it to throws clause.
Further the javadocs of AutoCloseable#close states
While this interface method is declared to throw Exception, implementers are strongly encouraged to declare concrete implementations of the close method to throw more specific exceptions, or to throw no exception at all if the close operation cannot fail.
Upvotes: 0
Reputation: 115338
You are right that close()
method defined in AutoClosable
throws exception. However other interface named Closable
that extends AutoClosable
redefines this method as following:
void close() throws IOException
All IO related classes implement Closable
, so their close()
method throws IOException
. But your method throws it too, so in your code no-one catches this exception. As always it will be caught by upper layer of your application or by JVM itself if no-one catches it before.
Upvotes: 0
Reputation: 4411
Java catches and suppresses exceptions thrown by the close method in a try-with-resources block.
You can read more about this here, see in particular the paragraph after the second code sample. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Upvotes: 2