10.6 Control Flow Changes in trycatchfinally

 <  Day Day Up  >  

10.6 Control Flow Changes in try/catch/finally

As we've seen throughout this chapter, the throw statement changes the flow of a program. When the interpreter encounters a throw statement, it immediately stops what it's doing and transfers program control to eligible catch and finally blocks. However, it is also quite legal for those catch and finally blocks to change program flow again via return (in the case of a method or function) or break or continue (in the case of a loop). Furthermore, a return , break , or continue statement can also appear in a try block.

To learn the rules of flow changes in the try/catch/finally statement, let's look at how the return statement affects program flow in a try , catch , and finally block. The following code examples contain a method, changeFlow( ) that demonstrates a control flow in various hypothetical situations. Note that, in all cases, the behavior of the changeFlow( ) method would be the same if it were a standalone function.

Example 10-1 shows a return statement in a try block, placed before an error is thrown. In this case, the method returns normally, and no error is ever thrown or handled. However, before the method returns, the finally block is executed. Note that you're unlikely to see code exactly like Example 10-1 in the real world. In most applied cases, the return statement would occur in a conditional statement and execute in response to some specific condition in the program.

Example 10-1. Using return in try, before throw
 function changeFlow ( ):Void {   try {     return;     throw new Error("Test error.");   } catch (e:Error) {     trace("Caught: " + e);   } finally {     trace("Finally executed.");   }   trace("Last line of method."); } // Output when   changeFlow( )   is invoked: Finally executed. 

Example 10-2 shows a return statement in a try block, placed after an error is thrown. In this case, the return statement is never executed because an error is thrown before it is reached. Once the error is caught and the try/catch/finally completes, execution resumes after the try/catch/finally statement, and the method exits at the end of the method body. Again, Example 10-2 demonstrates a principle but is atypical of real-world code, which would normally throw the error based on some condition.

Example 10-2. Using return in try, after throw
 function changeFlow ( ):Void {   try {     throw new Error("Test error.");     return;   } catch (e:Error) {     trace("Caught: " + e);   } finally {     trace("Finally executed.");   }   trace("Last line of method."); } // Output when   changeFlow( )   is invoked: Caught: Test error. Finally executed. Last line of method. 

Example 10-3 shows a return statement in a catch block. In this case, the return statement executes when the work of error handling is done, and the code after the try/catch/finally statement never executes. However, as usual, before the method returns, the finally block is executed. Unlike Examples 10-1 and Example 10-2, this code is typical of a real-world scenario in which a method is aborted due to the occurrence of an error.

Example 10-3. Using return in catch
 function changeFlow ( ):Void {   try {     throw new Error("Test error.");   } catch (e:Error) {     trace("Caught: " + e);     return;   } finally {     trace("Finally executed.");   }   trace("Last line of method."); } // Output when   changeFlow( )   is invoked: Caught: Test error. Finally executed. 

Last, Example 10-4 shows a return statement in a finally block. In this case, the return statement executes when the finally block executes (as we learned earlier, a finally block executes when its corresponding try block completes in one of the following ways: without errors, with an error that was caught, with an error that was not caught, or due to a return , break , or continue statement). Notice that the return statement in Example 10-4 prevents any code in the method beyond the try/catch/finally statement from executing. You might use a similar technique to quit out of a method after invoking a block of code, whether or not that code throws an exception. In such a case, you'd typically surround the entire try/catch/finally block in a conditional statement ( otherwise the remainder of the method would never execute!).

Example 10-4. Using return in finally
 function changeFlow ( ):Void {   try {     throw new Error("Test error.");   } catch (e:Error) {     trace("Caught: " + e);   } finally {     trace("Finally executed.");     return;   }   trace("Last line of method.");  // Not executed. } // Output when   changeFlow( )   is invoked: Caught: Test error. Finally executed. 

If a return statement occurs in a finally block after a return has already been issued in the corresponding try block, then the return in the finally block replaces the return already in progress.

 <  Day Day Up  >  


Essential ActionScript 2.0
Essential ActionScript 2.0
ISBN: 0596006527
EAN: 2147483647
Year: 2004
Pages: 177
Authors: Colin Moock

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net