I never properly understood the use of the finally statement. Can anyone tell me what the difference is between:
try {
a;
block;
off;
statements;
} catch (Exception e) {
handle;
exception;
e;
} finally {
do;
some;
cleanup;
}
on the one hand and:
try {
a;
block;
off;
statements;
} catch (Exception e) {
handle;
exception;
e;
}
do;
some;
cleanup;
On the other
They differ if
- the
try
-block completes by throwing ajava.lang.Throwable
that is not ajava.lang.Exception
, for instance because it is ajava.lang.Error
such asAssertionError
orOutOfMemoryError
. - the try-block completes abruptly using a control flow statement such a
continue
,break
orreturn
- the catch-block completes abruptly (by throwing any throwable, or using a control flow statement)
More generally, the java language guarantees that a finally block is executed before the try-statement completes. (Note that if the try-statement does not complete, there is no guarantee about the finally. A statement might not complete for a variety of reasons, including hardware shutdown, OS shutdown, VM shutdown (for instance due to System.exit
), the thread waiting (Thread.suspend()
, synchronized
, Object.wait()
, Thread.sleep()
) or being otherwise busy (endless loops, ,,,).
So, a finally
block is a better place for clean-up actions than the end of the method body, but in itself, still can not guarantee cleanup exeuction.
finally
block executes always.
finally
block is used for cleanup, like to free resources used within try
/catch
, close db connections, close sockets, etc.. even when an unhandled exception occurs within your try
/catch
block.
The only time the finally
block doesn't execute is whensystem.exit()
is called in try
/catch
or some error occurs instead of an exception.
The error in the description above means when Java application exit with conditions like Out Of Memory error. I see some downvotes :( for this reason it seems.
The main difference is that the catch
section might itself throw an exception, break out of a surrounding block, or return from the current method. In that case do; some; cleanup;
is not executed.
With a finally
block, it is guaranteed that that code will be executed.
It's basically a bad idea to catch all exceptions - so you need to consider what will happen if an uncaught exception propagates up out of your try/catch or try/catch/finally block. Finally blocks allow you to clean up on the way out.
Also:
- The catch block might throw an exception
- You may want to return from the try block
In short, if you want some code to be executed when you leave the try/catch block however you're leaving it (aside from the process being terminated very hard), finally is your friend.
In proper coding style you don't want to do a catch all as below.
try{
[some task]
}
catch
{
}
What you would want to do is catch specific known errors.
try{
[some task]
}
catch(Exception ex)
{
if([known execption])
[ignore]
else
throw(ex);
}
[Cleanup]
In this case your cleanup code will not be run in the case of an error being thrown again. So we add in the finally which will get run even if a new error is thrown.
try{
[some task]
}
catch(Exception ex)
{
if([known execption])
[ignore]
else
throw(ex);
}
finally
{
[Cleanup]
}
The "finally" block will always execute.
In your second example, the cleanup would not occur if the catch block rethrows the exception, or if an uncaught exception occurred in the try block.
From this forum on GeekInterview:
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
Simply one line of explanation:
regardless whether you caught an exception or not, codes in the finally
block will get executed.
the diff between the two pieces you gave here is: the codes in the piece without using finally
will never get executed.
to properly understand finally
, all you need to know is that finally
= guarantee!
you can use it to clean up, to help w/ user friendliness or to retry something
In the first example the finally block always gets executed even if you have a return statement in the try clause. The only time it doesn't get executed is when you have System.exit(0).
来源:https://stackoverflow.com/questions/3354823/how-to-use-finally