Tuesday, December 2, 2008

Displaying a Description of an Exception

Displaying a Description of an Exception

 

Throwable overrides the toString( ) method (defined by Object) so that it returns a string containing a description of the exception. You can display this description in a println( ) statement by simply passing the exception as an argument. For example, the catch block in the preceding program can be rewritten like this:

 

catch (ArithmeticException e) {

System.out.println("Exception: " + e);

a = 0; // set a to zero and continue

}

 

When this version is substituted in the program, and the program is run, each divide-by-zero error displays the following message:

 

Exception: java.lang.ArithmeticException: / by zero

 

While it is of no particular value in this context, the ability to display a description of an exception is valuable in other circumstances—particularly when you are experimenting with exceptions or when you are debugging.

 

Multiple catch Clauses

In some cases, more than one exception could be raised by a single piece of code. To handle this type of situation, you can specify two or more catch clauses, each catching a different type of exception. When an exception is thrown, each catch statement is inspected in order, and the first one whose type matches that of the exception is executed. After one catch statement executes, the others are bypassed, and execution continues after the try/catch block. The following example traps two different exception types:

 

// Demonstrate multiple catch statements.

class MultiCatch {

public static void main(String args[]) {

try {

int a = args.length;

System.out.println("a = " + a);

int b = 42 / a;

int c[] = { 1 };

c[42] = 99;

} catch(ArithmeticException e) {

System.out.println("Divide by 0: " + e);

} catch(ArrayIndexOutOfBoundsException e) {

System.out.println("Array index oob: " + e);

}

System.out.println("After try/catch blocks.");

}

}

LANGUAGE

This program will cause a division-by-zero exception if it is started with no commandline parameters, since a will equal zero. It will survive the division if you provide a command-line argument, setting a to something larger than zero. But it will cause an ArrayIndexOutOfBoundsException, since the int array c has a length of 1, yet the program attempts to assign a value to c[42].

 

Here is the output generated by running it both ways:

 

C:\>java MultiCatch

a = 0

Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks.

 

C:\>java MultiCatch TestArg

a = 1

Array index oob: java.lang.ArrayIndexOutOfBoundsException After try/catch blocks.

 

When you use multiple catch statements, it is important to remember that exception subclasses must come before any of their superclasses. This is because a catch statement that uses a superclass will catch exceptions of that type plus any of its subclasses. Thus, a subclass would never be reached if it came after its superclass.

 

Further, in Java, unreachable code is an error. For example, consider the following program:

 

/* This program contains an error.

A subclass must come before its superclass in

a series of catch statements. If not,

unreachable code will be created and a

compile-time error will result.

*/

class SuperSubCatch {

public static void main(String args[]) {

try {

int a = 0;

int b = 42 / a;

} catch(Exception e) {

System.out.println("Generic Exception catch.");

}

/* This catch is never reached because

ArithmeticException is a subclass of Exception. */

catch(ArithmeticException e) { // ERROR - unreachable

System.out.println("This is never reached.");

}

}

}

 

If you try to compile this program, you will receive an error message stating that the second catch statement is unreachable because the exception has already been caught.

 

Since ArithmeticException is a subclass of Exception, the first catch statement will handle all Exception-based errors, including ArithmeticException. This means that the second catch statement will never execute. To fix the problem, reverse the order of the catch statements.

No comments: