The try Statement

To catch exceptions in a Java program, you need a try statement. A simple try statement has a syntax similar to the following example:


try {
    double determinant = M[0][0]*M[1][1] - M[0][1]*M[1][0];
    System.out.println("The determinant of M is " + determinant);
}
catch ( ArrayIndexOutOfBoundsException e ) {
   System.out.println("M is the wrong size to have a determinant.");
   e.printStackTrace();
}

Here, the computer tries to execute the block of statements following the word “try”. If no exception occurs during the execution of this block, then the “catch” part of the statement is simply ignored. However, if an exception of type ArrayIndexOutOfBoundsException occurs, then the computer jumps immediately to the catch clause of the try statement. This block of statements is said to be an exception handler for ArrayIndexOutOfBoundsException. By handling the exception in this way, you prevent it from crashing the program. Before the body of the catch clause is executed, the object that represents the exception is assigned to the variable e, which is used in this example to print a stack trace.

However, the full syntax of the try statement allows more than one catch clause. This makes it possible to catch several different types of exception with onetry statement. In the above example, in addition to the possible ArrayIndexOutOfBoundsException, there is a possible NullPointerException which will occur if the value of M is null. We can handle both possible exceptions by adding a second catch clause to the try statement:


try {
    double determinant = M[0][0]*M[1][1] - M[0][1]*M[1][0];
    System.out.println("The determinant of M is " + determinant);
}
catch ( ArrayIndexOutOfBoundsException e ) {
   System.out.println("M is the wrong size to have a determinant.");
}
catch ( NullPointerException e ) {
   System.out.print("Programming error!  M doesn't exist." + );
}

Here, the computer tries to execute the statements in the try clause. If no error occurs, both of the catch clauses are skipped. If an ArrayIndexOutOfBoundsException occurs, the computer executes the body of the first catch clause and skips the second one. If a NullPointerExceptionoccurs, it jumps to the second catch clause and executes that.

Note that both ArrayIndexOutOfBoundsException and NullPointerException are subclasses of RuntimeException. It’s possible to catch all RuntimeExceptions with a single catch clause. For example:


try {
    double determinant = M[0][0]*M[1][1] - M[0][1]*M[1][0];
    System.out.println("The determinant of M is " + determinant);
}
catch ( RuntimeException err ) {
   System.out.println("Sorry, an error has occurred.");
   System.out.println("The error was: " + err);
}

The catch clause in this try statement will catch any exception belonging to class RuntimeException or to any of its subclasses. This shows why exception classes are organized into a class hierarchy. It allows you the option of casting your net narrowly to catch only a specific type of exception. Or you can cast your net widely to catch a wide class of exceptions. Because of subclassing, when there are multiple catch clauses in a try statement, it is possible that a given exception might match several of those catch clauses. For example, an exception of type NullPointerException would match catch clauses for NullPointerExceptionRuntimeExceptionException, or Throwable. In this case, only the first catch clause that matches the exception is executed.

The example we’ve given here is not particularly realistic. You are not very likely to use exception-handling to guard against null pointers and bad array indices. This is a case where careful programming is better than exception handling: Just be sure that your program assigns a reasonable, non-null value to the array M. You would certainly resent it if the designers of Java forced you to set up a try..catch statement every time you wanted to use an array! This is why handling of potential RuntimeExceptions is not mandatory. There are just too many things that might go wrong! (This also shows that exception-handling does not solve the problem of program robustness. It just gives you a tool that will in many cases let you approach the problem in a more organised way.)

Next: Throwing Exceptions