home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Sams Teach Yourself Visual J++ 6 in 21 Days
(Publisher: Macmillan Computer Publishing)
Author(s): Rick Leinecker
ISBN: 0672313510
Publication Date: 11/01/98

Bookmark It

Search this book:
 
Previous Table of Contents Next


Handling Exceptions with try-catch

The first part of a try-catch clause, the try block, encloses those statements that might throw an exception. Here is the syntax of a typical try block:

try
{
    // Statements here might throw exceptions
}

The only code in the earlier example capable of throwing an exception is the myDivide() method. However, any number of legal Java statements that have the potential to throw an exception can be included in the try block. As you can see, I intentionally supply myDivide() with parameters that will cause an exception to be thrown. Specifically, the second integer passed to the method is zero.

If you had additional lines of code following myDivide(10,0), they wouldn’t be executed. Instead, myDivide() would throw an exception that would immediately stop program execution at that point, and would then drop into the catch portion of the try-catch clause.

Following the try block are one or more catch blocks you can use to trap and process exceptions. This is the catch block syntax:

catch( ThrowableClassName variable)
{
    // Handle the error here
}

Although I supplied only one catch block in the myDivide() exception handler, any number could have been provided. However, because the myDivide() method throws only one exception, you have to catch that one. In this example, I merely output a line of text to prove that the exception was indeed caught. In the case of multiple catches, the try-catch clause has the following syntax:

try
{
    // Do stuff here that might throw an exception
}
catch( ThrowableClassName1 variable)
{
    // Handle the exception that throws ThrowableClassName1
}
catch( ThrowableClassName2 variable)
{
    // Handle the exception that throws ThrowableClassName1
}
catch( ThrowableClassName3 variable)
{
    // Handle the exception that throws ThrowableClassName1
}
catch( ThrowableClassName4 variable)
{
    // Handle the exception that throws ThrowableClassName1
}

For instance, suppose myDivide() was capable of throwing two different exceptions. In this case, you would provide a catch block for each of the possible exceptions:

try
{
    int y = myDivide( 10, 0);
}
catch( ArithmeticException e)
{
    System.out.println( "Have caught an ArithmeticException.");
}
catch( MyOwnException e)
{
    System.out.printin( "Have caught MyOwnException.");
}

The exception that is thrown is compared to the argument for each catch block in the order (the catch argument can be an object or an interface type). When a match is found, that catch block is executed. If no match is found, the exception propagates down the call stack, where it is compared against potential exception handlers until a match is found. And, as always, if no match is found, the program is aborted.

You can access the instance variables and methods of exceptions just as you can for any other object. With this in mind, you can invoke the exception’s getMessage() method to get information on the exception—getMessage() is a method defined in the Throwable class:

System.out.println( e.getMessage());

The Throwable class also implements several methods for dealing with the call stack when an exception occurs (such as printStackTrace(), which outputs the call stack to the display). The Throwable subclass you create can implement additional methods and instance variables. To find out which methods an exception implements, look at its class and superclass definitions.

Unlike C++, Java’s try-catch clause supports the use of an optional finally block. If defined, this is guaranteed to execute, regardless of whether an exception is thrown. As a result, you can use it to perform any necessary cleanup operation (closing files and streams, releasing system resources, and so on) that your methods require before the flow of control is transferred to another part of the program. This is the syntax of the finally block:

finally
{
    // Statements here are executed before control transfers
}

In the context of the myDivide() example, a finally block might look like this:

try
{
    int y = myDivide( 10, 0);
}
catch( ArithmeticException e)
{
    System.out.printin( "Have caught an ArithmeticException.");
}
catch( MyOwnException e)
{
    System.out.printin( "Have caught MyOwnException.");
}
finally
{
    System.out.printin( "cleaning up. . . ") ;
    // Do any clean-up work here
}

Upon execution of the finally block, control is transferred out of the try-catch clause. Typically, whatever event caused the try statement to terminate (fall-through the execution of a break, continue, or return statement, or the propagation of an exception) dictates where the flow of control will resume.

The finally block could also execute a jump statement. This would cause another unconditional control transfer outside its block, or cause another uncaught exception to be thrown. In either case, the original jump statement is abandoned, and the new unconditional control transfer (or exception) is processed.

All jump statements (break, continue, return, and throw) transfer control unconditionally. Whenever one causes control to bypass a finally block, the control transfer pauses while the finally part is executed, and it continues if the finally part finishes normally.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.