Is the finally block always executed ???

N

Neroku

Hi, I'm trying to know if the finally block in a try-catch-finally
construction is always executed. Throwing another exception inside the
catch block doesn't seem to skip the finally block execution. But I
don't understand why, consider the following code:

class Example
{
public static void main(String []args)
{
try{
throw new Exception();
}catch(Exception e)
{
throw new RuntimeException("Hello");
}finally{
System.out.println("Finally Reached");
}
}
}

It always prints:
Finally Reached

When the exception inside the catch block is thrown, it should be
delivered to the java virtual machine, isn't it? so java should kill
this program at that point, but it does not.
Any ideas?
Is it possible to define the finally block and skip it during
execution?

TIA
 
T

thelemmings

Hi,

Finally executes unconditionnally, you can't skip it. That is the
whole point of it: you are certain that in all cases it will be
executed, so you can, for example, go back to a previous state or
close a resource, whatever happens in your try/catch block.

A simple example would be, in a GUI, setting back the cursor to the
default arrow, even if something fails. Forgetting to set back the
cursor to its normal state and leaving it as an hourglass can be very
confusing for a user.

If you want some code to be executed conditionnally, just don't put it
inside a finally block:

try {
myCode();
throw new Exception();
}
catch (Exception e) {}

notExecuted();

Luc
 
T

Tom Hawtin

Neroku said:
Hi, I'm trying to know if the finally block in a try-catch-finally
construction is always executed. Throwing another exception inside the
catch block doesn't seem to skip the finally block execution. But I
don't understand why, consider the following code:

finally is supposed to be executed whichever way the block is executed.
For instance, usually you want to close a file stream whatever happened.

If you really don't want to execute the finally code after an exception
(and I suggest that is not the case), then add a flag:

boolean disposeResource = true;
Resource resource = acquire();
try {
...
} catch (SomeException exc) {
// Must ensure flag is set at last possible moment.
OtherException chainExc = new OtherException(exc, resource);
disposeResource = false;
throw chainExc;
} finally {
if (disposeResource) {
resource.dispose();
}
}

It is more usual to use something similar where the resource is returned
in the normal response. Therefore the resource should not be disposed of
iff the try block completes successfully. No matter where or what the
other exception, even if it is an OutOfMemoryError, abnormal termination
should dispose of the resource.

Tom Hawtin
 
E

Eric Sosman

Neroku said:
Hi, I'm trying to know if the finally block in a try-catch-finally
construction is always executed. Throwing another exception inside the
catch block doesn't seem to skip the finally block execution. But I
don't understand why, consider the following code:
> [snipped]

The purpose of finally is unconditional execution: if
you don't want unconditional execution, don't use finally.

It is possible to complete a finally block prematurely,
for example, by throwing an exception or executing `return'.
However, Java always tries to execute every finally block
associated with an active try block, no matter how the try
block itself terminates: normally, by returning, or by a
caught or uncaught exception.
 
T

Thomas Schodt

Neroku said:
Hi, I'm trying to know if the finally block in a try-catch-finally
construction is always executed. ....
Is it possible to define the finally block and skip it during
execution?

There are two ways to do this.

* In your try block; enter into a loop that *never* exits.

* Call Thread.stop() [deprecated] and catch ThreadDeath without
re-throwing it (causing more undefined behaviour).

<http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html#stop()>

/the throwing of ThreadDeath causes finally clauses of try statements to
be executed before the thread officially dies). If a catch clause
catches a ThreadDeath object, it is important to rethrow the object so
that the thread actually dies./
 
A

Andy Dingley

Hi, I'm trying to know if the finally block in a try-catch-finally
construction is always executed.

It's executed finally. That's what it's for, that's what it's supposed
to do. Don't fight it.
Throwing another exception inside the
catch block doesn't seem to skip the finally block execution.

Good. You've effectively done something _inside_ a block of code
which the finally clause is "guarding". So why would we ever expect it
to be skipped? It ought to be executed after the first block (that's
what it's defined to do) and it shouldn't be affected at all by
anything you do in the second block. Even if you set up nested
finallys (which is no worse than nesting exceptions anyway) then they
should still be executed in the appropriate order.

Bouncing exceptions around the place like this leads to nasty smelly
code too. Don't do it blindly.

When the exception inside the catch block is thrown, it should be
delivered to the java virtual machine, isn't it? so java should kill
this program at that point, but it does not.

You're misunderstanding the nature of exceptions and confusing them
with abends (abnormal terminations, run-time-errors etc. which _do_
kill the program). Exceptions are more powerful and much more useful
-- rather than everything grinding to a sudden halt (which is usually
bad, as it might leave files open/locked) an exception leaves
execution under the control of _your_ code, whilst at the same time
performing a significant jump out of the mainstream code in a cleaner
structure than line-by-line error checking. It's your choice as to
what happens next - you can terminate the thread / program with a
sudden crash, or you can fix things and continue.

In the simplest case, just throw the exception and let Java deal with
it. This is back to the abend case - a bit ugly, not fit for "live"
programs, but OK for a couple of line examples. You don't have to use
a finally clause.

Is it possible to define the finally block and skip it during
execution?

No. Either don't use finally, or else put the statement you're
concerned about inside a test inside the finally clause. Although
finally always executes, you don't have to execute every line of it!
 
A

Andy Dingley

You can skip finally if u call explicitly System.exit(1);

But you can't do it twice, because I'll have broken your fingers after
I read your first code with that in it. :cool:
 
P

Philipp

Andy said:
It's executed finally. That's what it's for, that's what it's supposed
to do. Don't fight it.


Good. You've effectively done something _inside_ a block of code
which the finally clause is "guarding". So why would we ever expect it
to be skipped? It ought to be executed after the first block (that's
what it's defined to do) and it shouldn't be affected at all by
anything you do in the second block. Even if you set up nested
finallys (which is no worse than nesting exceptions anyway) then they
should still be executed in the appropriate order.

Bouncing exceptions around the place like this leads to nasty smelly
code too. Don't do it blindly.

What is the execution order of the code posted by the OP?

1. try block (assume exc thrown)
2. catch block
2.1 code in catch block before exception
2.2 throw new exception
2.3 handle exception somewhere else
3. final block


or is it more like

1. try block (assume exc thrown)
2. catch block
2.1 code in catch block before exception
3. final block
4. throw new exception
5. handle exception somewhere else


Thanks Phil
 
C

Chris Uppal

Philipp said:
What is the execution order of the code posted by the OP?

1. try block (assume exc thrown)
2. catch block
2.1 code in catch block before exception
2.2 throw new exception
2.3 handle exception somewhere else
3. final block
[...]

1. try block (assume exc thrown)
2. catch block
2.1 code in catch block before exception
3. throw new exception
4. final block
5. handle exception somewhere else

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top