Reputation: 359
Here is a Java example I found online:
try{
//use buffering
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
try{
//deserialize the List
List<String> recoveredQuarks = (List<String>)input.readObject();
//display its data
for(String quark: recoveredQuarks){
System.out.println("Recovered Quark: " + quark);
}
}
finally{
input.close();
}
} catch(ClassNotFoundException ex){
//some exception handling
}
In the above, what are the benefits of using a try-finally block to execute some processing with the input before closing the input? In other words, what benefits would the code above have over something like this:
try{
//use buffering
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
List<String> recoveredQuarks = (List<String>)input.readObject();
for(String quark: recoveredQuarks){
System.out.println("Recovered Quark: " + quark);
}
input.close();
} catch(ClassNotFoundException ex){
//some exception handling
}
Upvotes: 0
Views: 1042
Reputation: 719336
The benefit of using try / finally ... or better still try-with-resource, is that it largely prevents resource leaks such as these:
and so on. Generally speaking, these problems happen because there is some path through the code where the stream / socket / whatever doesn't get closed. If that path is taken too often, attempts to open new streams, etcetera fail because the application has used all of the file descriptors available to it. If you use finally
correctly you can ensure that descriptors are released in all circumstances that matter.
It should also be noted that example you found on the net is not correct ... at least in theory. If the constructors for BufferedInputStream
or ObjectInputStream
were to throw an exception, then the finally
block would not be executed, and the FileInputStream
would be leaked.
A better way to write it is as follows:
try (InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInputStream input = new ObjectInputStream (buffer)) {
// do stuff
} catch (ClassNotFoundException ex){
// handling exception
}
Upvotes: 3
Reputation: 1205
There is a big difference: Imagine the following situation
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
try{
//do sth
throw new RuntimeException();
//do sth else
}
finally{
input.close();
}
In that case, with a finally block, the exception is thrown, but the finally block is executed and your input therefore closed.
If your code instead was
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
//do sth
throw new RuntimeException();
//do sth else
input.close();
Your InputStream would not get closed properly.
But since Java 7, the most elegant version would be to use try-with-resources, as mentioned in a comment to your question:
try (InputStream file = new FileInputStream ("quarks.ser");
InputStream buffer = new BufferedInputStream (file);
ObjectInput input = new ObjectInputStream (buffer);) {
//do sth
throw new RuntimeException ();
//do sth else
}
Upvotes: 7