views:

501

answers:

9

There are 3 permutations of a try...catch...finally block in java.

  1. try...catch
  2. try...catch...finally
  3. try...finally

Once the finally block is executed, control goes to the next line after the finally block. If I remove the finally block and move all its statements to the line after the try...catch block, would that have the same effect as having them in the finally block?

+1  A: 

Yes, there would be something very critically wrong.

And that is, your code would only run if there is an error.

Statements inside finally always run, regardless of an exception being thrown. That is the point.

Noon Silk
Cleanup code, for example, that you want to be run whether or not there's an error. That belongs in a finally block.
Michael Petrotta
You could make sure it errors every time by adding Throw new Exception(); as your last line in the Try block LOL
JumpingJezza
I think you misunderstood the "all the statements after catch block", to me it sounds like try { ...; } catch { ....; } *all the statements*;
Maxem
@JumpingJezza: Yes, but that statement is confused, because the code inside a finally isn't natively inside a try block, so an errors there need to be caught just as anywhere else. Your code inside a finally should be robust such that it actively goes out of its way to not generate exceptions.
Noon Silk
@Maxem: That is one interpretation, but I can't imagine the purpose of asking it, as it would be so bizar to be confused by that ...
Noon Silk
@Noon Silk: Jokes - definitely don't throw extra exceptions as they are resource expensive.
JumpingJezza
+24  A: 

A finally block is guaranteed to be executed even if an exception is raised. You use them to perform necessary clean-up like closing streams. The code after the finally block might never be reached.

From the java tutorial

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.

willcodejavaforfood
@articlestack also remember that finally block will not be called when System.exit(); is called.
Suresh S
@Suresh S: good point, but anyway in case of System.exit... nothing matters... (resources are freed at operating system level)
helios
+2  A: 

The finally block contains lines of code that should be executed regardless whether an exception has been caught or not. Even if you decide to stop code running in that method. So code after the t-c-f might not be executed, but the finally code is "guaranteed" (guaranteed in the sense of a non crashing immediately breaking non handleable error).

Sascha
what if try...catch is there. But im writing rest statements without finally block or in finally block? what is the difference?
articlestack
A: 

finally block especially used at the time of exception prevention. If any runtime error occurs, the program may lead to terminate. So at this time, it will call finally block before going to terminate the program. Usually 'finally' contains connection closing statements, save operations and file input, output close operations.

hemanth
+7  A: 

If I understand the question, you're asking what's the difference between:

try {
    Foo f = new Foo();
    f.bar();
}
finally
{
    Foo.baz();
}

And:

// This doesn't actually compile because a try block needs a catch and/or finally block
try {
    Foo f = new Foo();
    f.bar();
}
Foo.baz();

Or, more likely:

Foo f = new Foo();
f.bar();
Foo.baz();

The difference is that if either new Foo() or f.bar() throw an exception, the finally block will get executed in the first case, but that Foo.baz() won't get executed in the last two cases: instead control will skip over Foo.baz() while the JVM looks for an exception handler.


EDIT

Responding to your comment, what about:

Foo f = new Foo();
try {
    f.bar();
}
catch (Exception ex)
{
    // ...
}

f.baz();

You are right that, assuming the catch block doesn't rethrow the exception, or return from the method indicating a failure occured, then f.baz() gets called regardless of whether there was an exception. Even in that case, however, the finally block serves as documentation that f.baz() is used for cleanup.

More importantly, the fact that an exception was thrown usually is important, so it's very hard to write code that continues on doing whatever it was doing without knowing that an exception was thrown. There are times that exceptions indicate silly things that you can ignore, and in that case you should swallow the exception. More often, however, you will want to signal failure, either be rethrowing the exception (or throwing a different exception) or returning from the method with an error code.

For example, if f.bar() is supposed to convert a String to an Double, and on failure it throws a NumberFormatException, then code after the try block probably needs to know that the String was not actually converted to a Double. And, so, in general you won't want to continue after the catch block. Instead, you'll want to signal failure. This is known as "abort on failure" (compared to "resume on failure," which probably should be called "muddle on after failure with your fingers crossed").

Except in special cases you may be able to muddle on. For instance, the catch block could set the relevant Double to Double.NaN which is designed specifically to propagate errors correctly in math expressions. Even in that case, the finally block serves as documentation that f.baz() is involved in some kind of cleanup.

Max Lybbert
neither the first nor the second code snippet won't compile. `f` is not defined in `f.baz()`. (Just calling `baz()` without `f` would do)
Carlos Heuberger
You're right. Thanks. Fixed.
Max Lybbert
I was saying that try and catch both blocks ae present. Now what is the need of finally? Because if error has been caught and specific action has been taken then the next statement (either finally{} or the statement after catch{}) shall be executed.
articlestack
@aticlestak: I've edited the article to hopefully answer your question. The case you describe turns on the philosophy about how to use exceptions.
Max Lybbert
+10  A: 
Sisyphus
i got the same answer by my manager some mins ago
articlestack
+1  A: 

If your code never throws exception, or you are consuming all exception that will be correct. That is not what always happens.

fastcodejava
A: 

Two months ago I wrote a post for the reason behind 'finally' in a try/catch.

Aware that a link gets in the way of editing in a wiki style fashion here.

It is a self contained post which merely copying it over wouldn't work as you would miss the followup comment which also adds value.

Cue
A: 

code in finally block executes anyway (exception or no exception). Without it you should write the code one time in catch and one time after try statement.

Xaqron
Well... writing it two times, once at the end (inside) of the `try` block and once at the end (inside) of the `catch` block, is almost the same as writing it once after the whole try-catch command. Actually you risk catching an Exception in that code and having it executed a second time inside the catch.
Carlos Heuberger
I meant if somebody doesn't know what is finally block purpose is
Xaqron