Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is finally block really necessary for the clean up code (like closing streams)?

I am very confused as to why do I need to need to put the clean-up code like closing streams in a finally block.

I've read that the code in finally block will run no matter what (whether there's an exception); and after the finally block runs, the rest of the method continues.

My question is: if the rest of the method has to continue then why don't I put the clean-up code after my try/catch block in a function?

like image 533
Ankit Avatar asked Aug 20 '12 10:08

Ankit


People also ask

Is it necessary to have finally block?

Yes, it is not mandatory to use catch block with finally. You can have to try and finally.

Why you need to close the streams in finally block?

The finally block is mostly used during exception handling with try and catch to close streams and files. The code in finally block is executed irrespective of whether there is an exception or not. This ensures that all the opened files are properly closed and all the running threads are properly terminated.

Can we skip finally block?

You cannot skip the execution of the final block. Still if you want to do it forcefully when an exception occurred, the only way is to call the System.

Is finally block is optional?

The finally block is optional and provides a mechanism to clean up regardless of what happens within the try block. Use the finally block to close files or to release other system resources. The try block of the writeList method that you've been working with here opens a PrintWriter .


2 Answers

My question is; if the rest of the method has to continue then why do I not put the clean-up code after my try/catch block in a function.

Basically, like this:

InputStream is = ...
try {
   // use stream
} catch (IOException ex) {
   // report / recover
}
is.close();

But what happens if the // use stream section throws a different (e.g. unchecked) exception? Or the // report / recover code? In either case the close() call doesn't happen. (And what if there is a break or return statement in those blocks?)

It is possible to implement it this way in theory. The problem is making sure that the code always (i.e. ALWAYS) runs. And it is difficult to do that without catching a whole bunch of exceptions that you shouldn't be catching ... and won't be able to deal with properly if you do catch.

All in all, finally is the better solution.

  • it is simpler than the convolutions you otherwise need to do to handle the situation properly, and
  • it is more reliable than a typical half-hearted attempt.

And it is even simpler / more reliable if you can use the new Java 7 "try with resources" form in which the finally is taken care of automatically.


I would add that your characterization of when the finally clause is executed is a bit inaccurate. In reality, the finally block is executed no matter how the try block terminates, including:

  • when the try block drops off the end,
  • when it throws an exception ... irrespective of whether the exception is caught at this level, or
  • when it executes a return, continue or break.

In fact, the only cases where the finally block does not execute are if the try block calls System.exit() or the JVM crashes. (Or if it goes into an infinite loop ...)

like image 169
Stephen C Avatar answered Sep 25 '22 00:09

Stephen C


The finally block will always run if an uncaught exception is thrown, but the rest of the code in the method will be skipped.

So if you put clean-up code after the finally block, it won't get called if there is an exception.

like image 33
mikera Avatar answered Sep 25 '22 00:09

mikera