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?
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.
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
orbreak
.
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 ...)
In case you encounter an unexpected exception (not caught and handled).
If an Exception
occurs, ie, the try block is executed, then, rest assured, the finally
block will also be executed. It's just a safeguard option instead of putting an unreliable assumption that the rest of the method will get executed.
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.
Because the clean-up of your code is related to your try
to do an action that attempts to open resources etc and logically it should be as part of the final
clause as it is the last action related to your try
.
It would not make sense for example to close a file or connection 100 lines later due to some processing you have to do before returning.
You got the results. No exception, release the resources. Best to do it in finally
so that your code is cleaner as it is always executed
after the finally block runs rest of the method continues
This is only true if there was no exception caught. If an exception happens inside the try block the catch block will be executed (if there is one for this exception), the finally block will be executed, and then control is given to the caller of the method if the catch block throws the exception further, without running any further code in this method.
EDIT: clarify that catch would have to return of course, and not just eat the exception.
My question is; if the rest of the method has to continue then why not I put the clean code after my try/catch block in a function.
You can do so but you have to call this function again in finally block by passing object references( non-java resources) that needs to be closed. Because if this function is not finally block and if any exception occurs your entire method will be skipped without closing non-java reources.
Also you can use java7 feature -> try-catch with resources. Non-java resources will be automatically closed. You do not need to use finally block.
Maybe there is a slight misunderstanding here (or this is myself who misunderstand). The finally block is run whether a method exits on exceptional conditions or not, e.g.
try {
throw new Exception();
}
finally {
// Block of code will be called before the method exits as exception is thrown
}
Note that there is (very) few exception to this rule, as, for instance:
try {
System.exit(-1);
}
finally {
// Block of code will be called before the method exits as exception is thrown
}
This is a (quite dangerous) case where the program will exit without executing the finally block.
finally block as good for people as for compiler.
Take in to attention not only compiler but also human who will read your code. It would be much easy to edit code if clean-up part is in the finally block.
Finally Block will 100% surely execute try/catch will completely execute or Not.
So if u want to release the system resources u write the code in finally block. and return statements of the methods also.
来源:https://stackoverflow.com/questions/12035688/is-finally-block-really-necessary-for-the-clean-up-code-like-closing-streams