The Artima Developer Community
Sponsored Link

Legacy Design Forum
Finalization and Cleanup

Advertisement

Advertisement

This page contains an archived post to the Design Forum (formerly called the Flexible Java Forum) made prior to February 25, 2002. If you wish to participate in discussions, please visit the new Artima Forums.

Message:

Be careful "returning" from a "finally"

Posted by Kevin Jessup on January 11, 2002 at 4:10 PM

Hi All,

On the subject of clean up, be careful of lost exceptions and attempting to return a value from within a finally clause.

The following demo shows exceptions being generated in a variety of ways. Note that the "main()" calls four methods, m1, m2, m3 and m4. All generate exceptions. Step through (or just run) the code and notice how method m3() illustrates the classic "lost exception", and that method m4() shows how any and all ALL exceptions are lost when your return a variable from within a "finally." Also notice the illustration of "try - finally" without a "catch" clause.


class Test {

Test () {
}

public void m1 () throws Exception {
System.out.println("\nm1 about to throw exception...");
throw new Exception("** EXCEPTION 1 **");
}

public void m2 () throws Exception {
try {
System.out.println("\nm2 about to throw exception...");
throw new Exception("** EXCEPTION 2 **");
}
finally {
System.out.println("m2 in finally");
}
}

public void m3 () throws Exception {
try {
System.out.println("\nm3 about to throw exception...");
throw new Exception("** EXCEPTION 3 **");
}
finally {
System.out.println("m3 in finally");
throw new Exception("** ORIGINAL EXCEPTION MASKED **");
}
}

public boolean m4 () throws Exception {
try {
System.out.println("\nm4 about to throw exception...");
try {
// does nothing
if (false)
throw new Exception("** M4 NESTED EX **");
}
catch (Exception ex) {
System.out.println("m4 nested try caught " + ex.toString());
}

// force an array out-of-bounds exception
int myInts[] = {1, 2};
int x = myInts[3];
}
finally {
System.out.println("m4 in finally");
return (true); // by returning within a finally we have lost previous exceptions
}
}


public static void main (String[] args) {

Test test = new Test();

// see if m1() throws an exception
try {
test.m1();
System.out.println("Main now after m1 call");
} catch (Exception ex) {
System.out.println("Main got m1 exception " + ex.toString());
}

// see if m2 throws an exception
try {
test.m2();
System.out.println("Main now after m2 call");
} catch (Exception ex) {
System.out.println("Main got m2 exception " + ex.toString());
}

// see if m3 throws an exception
try {
test.m3();
System.out.println("Main now after m3 call");
} catch (Exception ex) {
System.out.println("Main got m3 exception " + ex.toString());
}

// see if m4 throws an exception
try {
test.m4();
System.out.println("Main now after m4 call");
} catch (Exception ex) {
System.out.println("Main got m4 exception " + ex.toString());
}

}

}


The output is as follows...


****

m1 about to throw exception...
Main got m1 exception java.lang.Exception: ** EXCEPTION 1 **

m2 about to throw exception...
m2 in finally
Main got m2 exception java.lang.Exception: ** EXCEPTION 2 **

m3 about to throw exception...
m3 in finally
Main got m3 exception java.lang.Exception: ** ORIGINAL EXCEPTION MASKED **

m4 about to throw exception...
m4 in finally
Main now after m4 call

***


So make sure you don't intentionally or accidentally put a return in the finally block when you meant the return statement to in fact be the LAST line of the method AND outside of the finally clause. And as usual, be wary of the "lost exception", as illustrated by m3() in the above example.

Kevin





Replies:

Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2009 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us