aspose file tools*
The moose likes Beginning Java and the fly likes try, catch, finally and return Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "try, catch, finally and return" Watch "try, catch, finally and return" New topic
Author

try, catch, finally and return

James Hodgkiss
Ranch Hand

Joined: Jan 22, 2004
Posts: 401
I'm trying to research how to ensure the finally block is executed in my method that may throw an exception. E.g.,



According to this site... "The code inside the finally clause will always be executed, even if an exception is thrown from within the try or catch block. If your code has a return statement inside the try or catch block, the code inside the finally-block will get executed before returning from the method."

But this other page says... "Note that the finally block is executed always except when the return statement is executed."

And this one says... "A Finally block will be executed after a try block if no exception has been thrown or after a catch if an exception was thrown. This means that a finally block can be used as 'clean up' - a place to close files or connections etc, whether an exception is thrown or not."

Some I'm not too sure!... Does anyone know for sure? I'm pretty sure I have experienced different behaviours in the past with different JVMs/KVMs, so running some tests may not prove conclusive.

Could anyone modify my code to ensure that the finally block is executed no matter what?

Thanks,
James
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

The finally block is executed no matter what.

(Actually, that's not quite true. If the try block never ends, for example if there's an infinite loop in it, then the finally block never starts. Same if the catch block never ends. And if you call System.exit() in either of them, then the finally block is not executed. But that's all. Any other behaviour is a bug.)
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18710
    
  40

But this other page says... "Note that the finally block is executed always except when the return statement is executed."


Not only is this statement wrong -- but if you look at the output of the code in the article, it clearly shows that the finally block is executed, even when the return statement is executed.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19670
    
  18

Although the writers third quote have an unfortunate way of expressing themselves, they are right. The first quote is also right.

I find it disturbing that javabeginner.com is making such false statements. It will cause many beginners to get the wrong idea.


Since either the try block or the catch block finishes, there is no need for a return statement in the finally block.

And Paul is right - System.exit is the only normal circumstance that causes a finally block to be skipped. Other circumstances are anything that causes the entire JVM to abort - errors in native code, operating system errors, hardware errors, that kind of thing. Also things you have absolutely no control over.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38348
    
  23
The Java Language Specification tells you in which circumstances finallies and catches are executed. It doesn't tell you how to spell finallies, however.
It also has several places here, for example, where "abrupt completion" is defined. A "return" might constitute abrupt completion.

You will have to go through the Java Language Specification for the different places where abrupt completion is described and compare them with the first link I gave.
Francisco Montes
Ranch Hand

Joined: Sep 30, 2009
Posts: 30
I found very interesting this thread and wanted to illustrate it with a code example for everybody. In this case, the catch clause contains a return statement.


The output is as follows:
Calling go
Entered catch
Entered finally
Back from go: ok

We can see that when execution hits return it does not immediately return, but rather gives the finally block a chance to execute before actually returning.


SCJP 1.6
Laurent Menten
Greenhorn

Joined: Jun 30, 2011
Posts: 1

Actually, it seems that the finally clause is executed after the return expression is evaluated but before the return is completed.



before call : value = 0
in try : value = 0
in finally : value = 1
after call : value = 2
returned value = 1

Senthil Kumar Sekar
Ranch Hand

Joined: Aug 08, 2010
Posts: 45


No matter what finally block will be executed except for one condition.
Its System.exit(0) --> When JVM is crashed. Thats the only situation finally block will not be executed.


Even though its an old thread, hope this mite help someone.

Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

What about System.exit(5)?
Ove Lindström
Ranch Hand

Joined: Mar 10, 2008
Posts: 326

Even more fun...



Then the return value will be overridden.
Senthil Kumar Sekar
Ranch Hand

Joined: Aug 08, 2010
Posts: 45

@Stephen - the value passed for System.exit() call can be any non zero +ve integer value which indicates abnormal termination of JVM.

"return" call also ensures that the finally block is executed.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38348
    
  23
Laurent Menten welcome to the Ranch

There should be something useful in the Java™ Language Specification, but that link isn't working at present. It should tell you about the execution of finally somewhere, but it won't be easy to understand.
Subrata Pradhan
Greenhorn

Joined: May 05, 2012
Posts: 8
is there any way to stop execution of finally block using deamon thread?? actually few days back one IBMer guy told me that we can stop the execution of finally block using deamon thread...so if its possible.. please explain...
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Subrata Pradhan wrote:is there any way to stop execution of finally block using deamon thread?? actually few days back one IBMer guy told me that we can stop the execution of finally block using deamon thread...so if its possible.. please explain...


There's nothing special about a finally block here. The only way to stop code in thread X from thread Y is:

1) Y calls Thread.interrupt() on X, AND (X is either in a method that throws InterruptedException or is checking its own interrupt flag) AND X then responds to that interrupt by stopping

OR

2) Y sets some flag that X checks during its execution.

There's no way for thread Y to just say, "Stop thread X's finally block" in general.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4363
    
    8

Subrata Pradhan wrote:is there any way to stop execution of finally block using deamon thread?? actually few days back one IBMer guy told me that we can stop the execution of finally block using deamon thread...so if its possible.. please explain...

My guess is what he meant is that a program exits when the last non-daemon thread ends. So daemon threads can be terminated abruptly. Which means that there may be cases where a finally block is not executed in a daemon thread, whereas in a non-daemon thread once the corresponding try block is entered then the finally block is guaranteed to run.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Matthew Brown wrote:
Subrata Pradhan wrote:is there any way to stop execution of finally block using deamon thread?? actually few days back one IBMer guy told me that we can stop the execution of finally block using deamon thread...so if its possible.. please explain...

My guess is what he meant is that a program exits when the last non-daemon thread ends. So daemon threads can be terminated abruptly. Which means that there may be cases where a finally block is not executed in a daemon thread, whereas in a non-daemon thread once the corresponding try block is entered then the finally block is guaranteed to run.


Ah, I see. That makes more sense. I couldn't figure out what he meant by "stopping it using a daemon thread."

@OP: As Matthew points out, one of the rules of the JVM is that it exits if there are only deamon threads left running. So if your try/catch/finally code is being executed in a daemon thread, and if all the non-daemon threads in the JVM complete, then the JVM will exit, and the daemon thread will die right then and there, even if it has not yet reached the finally block.

This is another case of what was talked about earlier in the thread: The finally block will always be executed if try and catch complete. But in cases where the JVM terminates abruptly such as System.exit() or all the non-daemon threads completing, then finally won't execute.

There are a couple of things worth noting though.

First, finally is never "skipped". That is if finally is not executed, neither is anything else that would have come after finally. If finally doesn't execute, it's because that thread (and usually the JVM) is dying right now.

Second, the way your question was worded, it sound like you want to use this feature of daemon threads to deliberately prevent the execution of finally. Don't do that. That would be an awful way to write code. Plus it would be very unreliable, as it would depend on the relative scheduling of your threads.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Rob Spoor wrote:
Since either the try block or the catch block finishes, there is no need for a return statement in the finally block.


I know this is an old comment in an old thread, but since the thread has been revived, I feel it's worth addressing this.

You should never (okay, there may be some weird special cases, but you'll know them when you find them--until then, assume "never"), never return, throw, continue, or break out of a finally block. We don't want finally to change the way the try statement completes. If the try/catch part is completing normally (because there was no exception, or if there was it was caught), then an exception in the clean-up should not change that. Likewise, if try/catch is complete abruptly (exception was thrown and not caught, or was caught and re-thrown), then the clean-up should not change that either.
Frederico Cunha
Greenhorn

Joined: Feb 15, 2013
Posts: 2
I'm sorry for going back and look for this subject, but after googling this seemed the most comprehensive site on the subject.

A small contribution to the cause.

if you use something like:




The result will be:
Calling go
Entered catch
Entered finally
Back from go: Not OK


The finally block is executed even if you have the "throw" and you actually end up changing the function's result.
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3446
    
  12
Frederico Cunha wrote:The finally block is executed even if you have the "throw" and you actually end up changing the function's result.

Which is why Jeff said in the post before yours that you should never return, throw, continue, or break out of a finally block


Joanne
Frederico Cunha
Greenhorn

Joined: Feb 15, 2013
Posts: 2
For those of you that are still sceptical on the subject and that imagine that a global variable may affect.



And the result is:
Calling go
Entered catch
Entered finally
Back from go: Not OK

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: try, catch, finally and return