what's the point in finally?

Discussion in 'Java' started by Crouchez, Aug 7, 2007.

  1. Crouchez

    Crouchez Guest

    try{
    //blah }
    catch(Exception ex){
    // }
    finally{ //do something }why not justtry{//blah}catch(Exception
    e){}//do something
    Crouchez, Aug 7, 2007
    #1
    1. Advertising

  2. Crouchez

    bugbear Guest

    Crouchez wrote:
    > try{
    > //blah }
    > catch(Exception ex){
    > // }
    > finally{ //do something }why not justtry{//blah}catch(Exception
    > e){}//do something
    >
    >


    What if your exception handling code throws an Exception?

    BugBear
    bugbear, Aug 7, 2007
    #2
    1. Advertising

  3. Crouchez

    Eric Sosman Guest

    Crouchez wrote:
    > try{
    > //blah }
    > catch(Exception ex){
    > // }
    > finally{ //do something }why not justtry{//blah}catch(Exception
    > e){}//do something


    For one thing, the finally clause will execute no matter
    how the try-ed code terminates: By throwing an Exception, by
    throwing some other kind of Throwable, by return-ing or by
    break-ing or by running all the way to its end -- the code
    in the finally clause will be executed regardless.

    Another point is that it is almost always wrong to catch
    Exception: You should catch IOException or InterruptedException
    or some other, more specific kind of condition (or conditions).
    The code in a catch clause is supposed to "deal with" the
    exceptional condition, which means you need to have anticipated
    the possibility and written code expressly for that outcome. It's
    just not possible to "deal" effectively with every possible kind
    of Throwable, so it's pretty much a given that some kinds of
    Throwable will not be caught. Would you like your cleanup code
    to execute anyhow? Then put it in the finally clause.

    Still another issue: Once you catch an Exception, that's the
    end of the line; Java's processing of it ceases once it's caught.
    So what do you do if you'd like to clean up "en passant" but
    let the original Exception propagate outward to your caller?
    You could re-throw the same Exception after cleaning up, or
    you could wrap the caught Exception in a new Exception of your
    own and throw that one instead, but both courses are clumsy.
    (The second is sometimes forced upon you for other reasons.)
    Put your cleanup code in the finally clause and you get exactly
    the desired effect without the extra running around.

    --
    Eric Sosman
    lid
    Eric Sosman, Aug 7, 2007
    #3
  4. Crouchez

    Michael Jung Guest

    bugbear <bugbear@trim_papermule.co.uk_trim> writes:
    > Crouchez wrote:
    > > try{
    > > //blah }
    > > catch(Exception ex){
    > > // }
    > > finally{ //do something }why not justtry{//blah}catch(Exception
    > > e){}//do something

    >
    > What if your exception handling code throws an Exception?


    In fact, if you throw an exception in the finally block you have a much
    toughre problem at hand. finally is used, e.g., to free resources in the good
    and the bad case. Or implement some code that should be executed regardless of
    whether you want the caller to get an exception or not.

    Consider try blocks without catch but with finally or whithout finally but
    catch.

    Michael
    Michael Jung, Aug 7, 2007
    #4
  5. Crouchez

    Roedy Green Guest

    what if you throw an exception you DON'T catch?
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Aug 7, 2007
    #5
  6. Crouchez

    Crouchez Guest

    Scenario A

    try{
    //blah
    }
    catch(Exception e){
    }
    finally{
    //do something
    }

    why not just...

    Scenario B

    try{
    //blah
    }catch(Exception e){
    }
    //do something


    OK right. I'm not following the arguments here. The //do something will
    always be called in both scenarios unless something isn't returned in the
    catch method? I don't understand why there is more use of resources either
    in Scenario B? So what's the use of finally?
    Crouchez, Aug 7, 2007
    #6
  7. Crouchez wrote:
    > Scenario A
    >
    > try{
    > //blah
    > }
    > catch(Exception e){
    > }
    > finally{
    > //do something
    > }
    >
    > why not just...
    >
    > Scenario B
    >
    > try{
    > //blah
    > }catch(Exception e){
    > }
    > //do something
    >
    >
    > OK right. I'm not following the arguments here. The //do something will
    > always be called in both scenarios unless something isn't returned in the
    > catch method? I don't understand why there is more use of resources either
    > in Scenario B? So what's the use of finally?


    In the second scenario //do something will not be called if, for
    example, there was a stack overflow, because StackOverflowError does not
    extend Exception.

    Also consider the case in which //blah contains a return statement. Code
    immediately after the try-catch-finally will not get executed. The
    finally block will.

    Second, catching and hiding Exception is such a dangerous thing to do
    that I don't really care whether finally is or is not needed in such
    code. I'm much more interested in:

    try{
    // blah
    }
    catch(SomeException e){
    // Do something about it
    }
    catch(AnotherException e){
    // Do something else
    }
    finally{
    // Clean up after blah
    }

    In this, much more realistic, case there may be exceptions that do not
    get caught, and with non-trivial catch blocks the catch blocks
    themselves may return or throw exceptions of their own. As before, none
    of the errors are being caught, and blah may contain a return statement.

    Most of the very, very few gotos I wrote when I was programming in C
    were substitutes for finally - situations in which there were a lot of
    logical returns, but some clean-up code that had to be run on the way
    out, regardless of why the function was finishing.

    Patricia
    Patricia Shanahan, Aug 7, 2007
    #7
  8. Crouchez

    Crouchez Guest

    "Patricia Shanahan" <> wrote in message
    news:...
    > Crouchez wrote:
    >> Scenario A
    >>
    >> try{
    >> //blah
    >> }
    >> catch(Exception e){
    >> }
    >> finally{
    >> //do something
    >> }
    >>
    >> why not just...
    >>
    >> Scenario B
    >>
    >> try{
    >> //blah
    >> }catch(Exception e){
    >> }
    >> //do something
    >>
    >>
    >> OK right. I'm not following the arguments here. The //do something will
    >> always be called in both scenarios unless something isn't returned in the
    >> catch method? I don't understand why there is more use of resources
    >> either in Scenario B? So what's the use of finally?

    >
    > In the second scenario //do something will not be called if, for
    > example, there was a stack overflow, because StackOverflowError does not
    > extend Exception.
    >


    are you sure? whether code throws an exception/error/throwable or not it
    will still get to //do something in both scenarios. With StackOverflowError
    or OutofMemoryError then the program often stops completely.

    > Also consider the case in which //blah contains a return statement. Code
    > immediately after the try-catch-finally will not get executed. The
    > finally block will.
    >


    Ahh i see this point. I thought return was the ultimate last in the chain -
    finally does indeed get called before return but i can't think of any reason
    to do that.
    Crouchez, Aug 7, 2007
    #8
  9. Crouchez

    Crouchez Guest

    "Crouchez" <> wrote in message
    news:aI%ti.54073$%...
    >
    > "Patricia Shanahan" <> wrote in message
    > news:...
    >> Crouchez wrote:
    >>> Scenario A
    >>>
    >>> try{
    >>> //blah
    >>> }
    >>> catch(Exception e){
    >>> }
    >>> finally{
    >>> //do something
    >>> }
    >>>
    >>> why not just...
    >>>
    >>> Scenario B
    >>>
    >>> try{
    >>> //blah
    >>> }catch(Exception e){
    >>> }
    >>> //do something
    >>>
    >>>
    >>> OK right. I'm not following the arguments here. The //do something will
    >>> always be called in both scenarios unless something isn't returned in
    >>> the catch method? I don't understand why there is more use of resources
    >>> either in Scenario B? So what's the use of finally?

    >>
    >> In the second scenario //do something will not be called if, for
    >> example, there was a stack overflow, because StackOverflowError does not
    >> extend Exception.
    >>

    >
    > are you sure? whether code throws an exception/error/throwable or not it
    > will still get to //do something in both scenarios. With
    > StackOverflowError or OutofMemoryError then the program often stops
    > completely.
    >
    >> Also consider the case in which //blah contains a return statement. Code
    >> immediately after the try-catch-finally will not get executed. The
    >> finally block will.
    >>

    >
    > Ahh i see this point. I thought return was the ultimate last in the
    > chain - finally does indeed get called before return but i can't think of
    > any reason to do that.
    >
    >


    you're right with the StackOverflowError or OutofMemoryError thing - finally
    does get called. Cheers for that
    Crouchez, Aug 7, 2007
    #9
  10. Crouchez

    bugbear Guest

    Crouchez wrote:
    > Scenario A
    >
    > try{
    > //blah
    > }
    > catch(Exception e){
    > }
    > finally{
    > //do something
    > }
    >
    > why not just...
    >
    > Scenario B
    >
    > try{
    > //blah
    > }catch(Exception e){
    > }
    > //do something
    >
    >
    > OK right. I'm not following the arguments here. The //do something will
    > always be called in both scenarios unless something isn't returned in the
    > catch method? I don't understand why there is more use of resources either
    > in Scenario B? So what's the use of finally?


    In your code there is no point in finally. If you had REAL exception handling,
    i.e. non empty exception blocks (which you should), the distinction
    may become more obvious.

    BugBear
    bugbear, Aug 7, 2007
    #10
  11. Crouchez wrote:
    > "Patricia Shanahan" <> wrote in message
    > news:...
    >> Crouchez wrote:
    >>> Scenario A
    >>>
    >>> try{
    >>> //blah
    >>> }
    >>> catch(Exception e){
    >>> }
    >>> finally{
    >>> //do something
    >>> }
    >>>
    >>> why not just...
    >>>
    >>> Scenario B
    >>>
    >>> try{
    >>> //blah
    >>> }catch(Exception e){
    >>> }
    >>> //do something
    >>>
    >>>
    >>> OK right. I'm not following the arguments here. The //do something will
    >>> always be called in both scenarios unless something isn't returned in the
    >>> catch method? I don't understand why there is more use of resources
    >>> either in Scenario B? So what's the use of finally?

    >> In the second scenario //do something will not be called if, for
    >> example, there was a stack overflow, because StackOverflowError does not
    >> extend Exception.
    >>

    >
    > are you sure? whether code throws an exception/error/throwable or not it
    > will still get to //do something in both scenarios. With StackOverflowError
    > or OutofMemoryError then the program often stops completely.


    I am sure. This program:

    public class StackOverflowTest {
    public static void main(String[] args) {
    try {
    try {
    badRecursion();
    } catch (Exception e) {
    System.out.println("Exception caught");
    } finally {
    System.out.println("In finally block");
    }
    System.out.println("After try-catch-finally");
    } catch (StackOverflowError e) {
    System.out.println("Caught " + e);
    }
    }
    static void badRecursion() {
    badRecursion();
    }
    }

    prints:

    In finally block
    Caught java.lang.StackOverflowError

    It does not reach the "After try-catch-finally" printout.

    In many cases a program could in theory continue after an Error, but it
    is usually not a good idea. Error implies that something is VERY wrong.


    >
    >> Also consider the case in which //blah contains a return statement. Code
    >> immediately after the try-catch-finally will not get executed. The
    >> finally block will.
    >>

    >
    > Ahh i see this point. I thought return was the ultimate last in the chain -
    > finally does indeed get called before return but i can't think of any reason
    > to do that.


    finally allows you to write return statements where they logically
    belong and yet be sure the method's clean-up code runs.

    When I saw try-catch-finally, I knew I would not miss "goto". The few
    goto's I wrote in C were all emulating a finally structure, making sure
    that no matter how I completed a function I would do the cleanup.

    Patricia
    Patricia Shanahan, Aug 7, 2007
    #11
  12. Crouchez

    bugbear Guest

    Crouchez wrote:
    >> Also consider the case in which //blah contains a return statement. Code
    >> immediately after the try-catch-finally will not get executed. The
    >> finally block will.
    >>

    >
    > Ahh i see this point. I thought return was the ultimate last in the chain -
    > finally does indeed get called before return but i can't think of any reason
    > to do that.


    I suggest you go back and read Patricia's comments (and code)
    after she says "I'm much more interested in: "

    It's good stuff, and will help you.

    BugBear
    bugbear, Aug 7, 2007
    #12
  13. Crouchez

    Daniel Pitts Guest

    On Aug 7, 7:53 am, "Crouchez" <>
    wrote:
    > "Patricia Shanahan" <> wrote in message
    >
    > news:...
    >
    >
    >
    > > Crouchez wrote:
    > >> Scenario A

    >
    > >> try{
    > >> //blah
    > >> }
    > >> catch(Exception e){
    > >> }
    > >> finally{
    > >> //do something
    > >> }

    >
    > >> why not just...

    >
    > >> Scenario B

    >
    > >> try{
    > >> //blah
    > >> }catch(Exception e){
    > >> }
    > >> //do something

    >
    > >> OK right. I'm not following the arguments here. The //do something will
    > >> always be called in both scenarios unless something isn't returned in the
    > >> catch method? I don't understand why there is more use of resources
    > >> either in Scenario B? So what's the use of finally?

    >
    > > In the second scenario //do something will not be called if, for
    > > example, there was a stack overflow, because StackOverflowError does not
    > > extend Exception.

    >
    > are you sure? whether code throws an exception/error/throwable or not it
    > will still get to //do something in both scenarios. With StackOverflowError
    > or OutofMemoryError then the program often stops completely.
    >
    > > Also consider the case in which //blah contains a return statement. Code
    > > immediately after the try-catch-finally will not get executed. The
    > > finally block will.

    >
    > Ahh i see this point. I thought return was the ultimate last in the chain -
    > finally does indeed get called before return but i can't think of any reason
    > to do that.




    One typical use case:
    try {
    return parseSomeXml();
    } catch (ParserException e) {
    throw new MyGenericException("Can parse xml", e);
    } catch (IOException e) {
    throw new MyGenericException("IO problem loading XML", e);
    } finally {
    cleanUpStuff();
    }
    Daniel Pitts, Aug 7, 2007
    #13
  14. Daniel Pitts wrote:
    >
    > One typical use case:
    > try {
    > return parseSomeXml();
    > } catch (ParserException e) {
    > throw new MyGenericException("Can parse xml", e);
    > } catch (IOException e) {
    > throw new MyGenericException("IO problem loading XML", e);
    > } finally {
    > cleanUpStuff();
    > }


    The trouble is that cleanUpStuff is usually declared to throw an
    exception. Therefore code like that is often incorrect or messy.

    My guess is that the evolution of Java went something like:

    o Start with C++ where resources are flushed explicitly and destructor
    do not throw. If you throw an exception from a destructor and the
    destructor is called due to an exception unwinding the stack then, IIRC,
    abort is called which by default calls terminate.

    o This makes try-catch-finally relatively natural. I believe catch
    (...) logically comes after catches with explicit exception types in
    C++. I guess catch-before-finally can also allow the exception object to
    depend upon the resource still being open (though generally a poor idea).

    o Java goes in for virtual methods and decorators. Unfortunately
    "ownership" of the resource is moved into the decorator (this would make
    sense if the "decorator" create the resource from a factory rather than
    being passed through the constructor).

    o In order to support such decorators (buffered output streams for
    example), all resources can throw exceptions when being closed. Closing
    an input stream is a classic example where a close declares that it
    throws an exception, but probably shouldn't.

    o We are now in a situation where finally needs to be inside the try
    block, but the syntax is the wrong way around.

    There is also the problem that the finally block will need a reference
    to the resource, even though the construction of the resource needs to
    be within the try-catch.

    So the general pattern should be:

    try {
    acquire-resource;
    try {
    decorate-resource;
    use-decorator;
    flush-decorator;
    } finally {
    release-resource;
    }
    } catch (ResourceException exc) {
    ... erm, do something sensible ...
    ... probably wrap in a different exception ...
    }

    Now, if the exception makes sense for the method to throw, the catch can
    be removed.

    With closures, such as methods within anonymous inner classes, the
    common code can be factored out (although with the current syntax, you
    will still end up with some highly verbose boilerplate).

    Tom Hawtin
    Thomas Hawtin, Aug 7, 2007
    #14
  15. Crouchez

    Crouchez Guest

    So...

    You can't actually catch or code in a contigency plan for an
    OutofMemoryError but with finally you can? because finally runs regardless
    of whether an exception or error is caught or not? ie. finally always runs
    if the JVM is?
    Crouchez, Aug 8, 2007
    #15
  16. Crouchez

    kaldrenon Guest

    On Aug 7, 10:53 am, "Crouchez" <>
    wrote:
    > are you sure? whether code throws an exception/error/throwable or not it
    > will still get to //do something in both scenarios. With StackOverflowError
    > or OutofMemoryError then the program often stops completely.


    public class Test
    {
    public static void main(String[] args)
    {
    try
    {
    return;
    }
    catch(Exception e){}
    finally
    {
    System.out.println("testing");
    }
    }
    }

    Output:
    "testing"
    kaldrenon, Aug 8, 2007
    #16
  17. Crouchez

    Wojtek Guest

    Crouchez wrote :
    > try{
    > //blah }
    > catch(Exception ex){
    > // }
    > finally{ //do something }why not justtry{//blah}catch(Exception
    > e){}//do something


    public void myMethod() throws MyException
    {
    try
    {
    grabSomeResources();
    somethingDangerous(); // throws MyException
    }
    finally
    {
    freeSomeResources();
    }
    }

    In the above the resources will always be freed.

    --
    Wojtek :)
    Wojtek, Aug 8, 2007
    #17
  18. Wojtek wrote:
    > try
    > {
    > grabSomeResources();
    > somethingDangerous(); // throws MyException
    > }
    > finally
    > {
    > freeSomeResources();
    > }
    > }
    >
    > In the above the resources will always be freed.


    Even if it fails to be acquired!

    The basic standard form is:

    acquire; try { use; } finally { release; }.

    Tom Hawtin
    Thomas Hawtin, Aug 8, 2007
    #18
  19. Crouchez

    Lew Guest

    Crouchez wrote:
    > You can't actually catch or code in a contigency [sic] plan for an
    > OutofMemoryError but with finally you can? because finally runs regardless
    > of whether an exception or error is caught or not? ie. [sic] finally always runs
    > if the JVM is?


    Not correct. You can catch Errors and /try/ to do something about them *in
    the catch block*, just like any other Throwable. The finally block is not the
    place to handle such things; the catch block is.

    That said, the reason you can't effectively catch an Error is that it
    represents a situation so fubared that there is no effective recovery
    available. Still, you can declare a catch block to attempt to minimize the
    damage.

    --
    Lew
    Lew, Aug 8, 2007
    #19
  20. Crouchez

    Twisted Guest

    On Aug 8, 6:13 pm, Lew <> wrote:
    > That said, the reason you can't effectively catch an Error is that it
    > represents a situation so fubared that there is no effective recovery
    > available. Still, you can declare a catch block to attempt to minimize the
    > damage.


    Curiously, I'd say that StackOverflowError, at minimum, may be an
    exception to this rule. I can imagine e.g.

    public int myMethod (int arg) {
    if (isBaseCase(arg)) return 0;
    try {
    return recursiveMyMethod(arg);
    } catch (StackOverflowError e) {
    throw new IllegalArgumentException("Argument " + arg + " to
    myMethod is too big.");
    }
    }

    The stack unwind "undoes" the damage of a stack overflow, since the
    stack ends up as stubby as it was before the recursive call. Of course
    the caller might still just upchuck on the IllegalArgumentException.
    It's not hard to imagine a less efficient nonrecursive version of
    myMethod being called, though, or some other such recovery depending
    on the situation, or the result of the IAE being a particular user
    operation failing without the whole app bombing.

    In multithreaded parallelized code, another way to "recover" from even
    OOME is to let it kill the thread it arises within. Another thread
    goes to allocate something and this forces a GC, which reclaims all
    the resources the now-dead thread held. Memory pressure thus leads to
    scaled-back parallelization. With a control thread that holds the job
    queues and has some ability to detect worker thread disappearance,
    jobs can be reissued. Performance degrades instead of the task
    bombing. A factory can attempt to recreate the missing worker threads
    after some time has elapsed. A "fat job" could cause half the threads
    to die but eventually be done with and the system would bounce back up
    to its usual performance after a while.

    Ultimately, how recoverable or irrecoverable any of these are is
    dependent on the requirements and details of what's being implemented.

    Certainly typical applications with user documents need to catch all
    of them, including and especially OOME, and do a panic-save of the
    user's session and unsaved data to where the next session will attempt
    to recover, at minimum. (Not over the original files in case of data
    corruption or other inconsistent transitional states caused by the
    interrupting throwable!) To be able to do this, the exception handler
    can trigger a graceful but non-memory-allocating shutdown that tells
    threads to quit, destroys displayed UI, and drops references to most
    objects other than those representing unsaved data, then call
    System.gc() (though this should probably not be necessary), then
    create some streams and save the unsaved data to the recovery file,
    then pop up an apologetic error message, before shutting down. The
    memory freed by first disposing of the previously-visible UI objects
    alone is probably sufficient to do this successfully during exit.
    Twisted, Aug 9, 2007
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gopi

    point to point protocol

    Gopi, Jul 13, 2004, in forum: VHDL
    Replies:
    1
    Views:
    470
    Mike Treseler
    Jul 13, 2004
  2. H aka N
    Replies:
    15
    Views:
    15,647
    Ben Jones
    Mar 2, 2006
  3. Motaz Saad
    Replies:
    7
    Views:
    6,482
  4. David Lozzi

    Try...Catch...Finally not firing finally?

    David Lozzi, Apr 23, 2007, in forum: ASP .Net
    Replies:
    12
    Views:
    793
    Alvin Bruney [MVP]
    May 11, 2007
  5. Saraswati lakki
    Replies:
    0
    Views:
    1,321
    Saraswati lakki
    Jan 6, 2012
Loading...

Share This Page