Stack Unwinding

When an exception is thrown but not caught in a particular scope, the method-call stack is "unwound," and an attempt is made to catch the exception in the next outer try block. This process is called stack unwinding. Unwinding the method-call stack means that the method in which the exception was not caught terminates, all local variables in that method go out of scope and control returns to the statement that originally invoked that method. If a TRy block encloses that statement, an attempt is made to catch the exception. If a try block does not enclose that statement, stack unwinding occurs again. If no catch block ever catches this exception and the exception is checked (as in the following example), compiling the program will result in an error. The program of Fig. 13.6 demonstrates stack unwinding.

Figure 13.6. Stack unwinding.

1 // Fig. 13.6: UsingExceptions.java 2 // Demonstration of stack unwinding. 3 4 public class UsingExceptions 5 { 6 public static void main( String args[] ) 7 { 8 try // call throwException to demonstrate stack unwinding 9 { 10 throwException(); 11 } // end try 12 catch ( Exception exception ) // exception thrown in throwException 13 { 14 System.err.println( "Exception handled in main" ); 15 } // end catch 16 } // end main 17 18 // throwException throws exception that is not caught in this method 19 public static void throwException() throws Exception 20 { 21 try // throw an exception and catch it in main 22 { 23 System.out.println( "Method throwException" ); 24 throw new Exception(); // generate exception 25 } // end try 26 catch ( RuntimeException runtimeException ) // catch incorrect type 27 { 28 System.err.println( 29 "Exception handled in method throwException" ); 30 } // end catch 31 finally // finally block always executes 32 { 33 System.err.println( "Finally is always executed" ); 34 } // end finally 35 } // end method throwException 36 } // end class UsingExceptions  

Method throwException Finally is always executed Exception handled in main  

When method main executes, line 10 in the TRy block calls method throwException (lines 1935). In the try block of method throwException (lines 2125), line 24 throws an Exception. This terminates the try block immediately, and control skips the catch block at line 26, because the type being caught (RuntimeException) is not an exact match with the thrown type (Exception) and is not a superclass of it. Method throwException terminates (but not until its finally block executes) and returns control to line 10the point from which it was called in the program. Line 10 is in an enclosing try block. The exception has not yet been handled, so the try block terminates and an attempt is made to catch the exception at line 12. The type being caught (Exception) does match the thrown type. Consequently, the catch block processes the exception, and the program terminates at the end of main. If there were no matching catch blocks, a compilation error would occur. Remember that this is not always the casefor unchecked exceptions, the application will compile, but run with unexpected results.

Категории