• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

try, catch, finally and return

 
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.)
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

 
Greenhorn
Posts: 1
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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

 
Ranch Hand
Posts: 45
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.

 
Saloon Keeper
Posts: 15484
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What about System.exit(5)?
 
Ranch Hand
Posts: 326
Android Mac OS X Firefox Browser
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Even more fun...



Then the return value will be overridden.
 
Senthil Kumar Sekar
Ranch Hand
Posts: 45
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@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
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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...
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Frederico Cunha
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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

 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic