The JavaTM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Essential Java Classes
Lesson: Handling Errors with Exceptions

## The catch Block(s)

> As you learned on the previous page, the `try` statement defines the scope of its associated exception handlers. You associate exception handlers with a `try` statement by providing one or more `catch` blocks directly after the `try` block:

> >     try {
> >         . . .
> >     } catch ( . . . ) {
> >         . . .
> >     } catch ( . . . ) {
> >         . . .
> >     } . . .

> There can be no intervening code between the end of the `try` statement and the beginning of the first `catch` statement. The general form of Java's `catch` statement is:

> >     catch (SomeThrowableObject variableName) {
> >         Java statements
> >     }

> As you can see, the `catch` statement requires a single formal argument. The argument to the `catch` statement looks like an argument declaration for a method. The argument type, SomeThrowableObject, declares the type of exception that the handler can handle and must be the name of a class that inherits from the `Throwable` class defined in the `java.lang` package. When Java programs throw an exception they are really just throwing an object, and only objects that derive from `Throwable` can be thrown. You'll learn more about throwing exceptions in How to Throw Exceptions.

> variableName is the name by which the handler can refer to the exception caught by the handler. For example, the exception handlers for the `writeList` method (shown later) each call the exception's `getMessage` method using the exception's declared name `e`:

> >     e.getMessage()

> You access the instance variables and methods of exceptions in the same manner that you access the instance variables and methods of other objects. `getMessage` is a method provided by the `Throwable` class that prints additional information about the error that occurred. The `Throwable` class also implements two methods for filling in and printing the contents of the execution stack when the exception occurred. Subclasses of `Throwable` can add other methods or instance variables. To find out what methods an exception implements, check its class definition and definitions for any of its ancestor classes.

> The `catch` block contains a series of legal Java statements. These statements are executed if and when the exception handler is invoked. The runtime system invokes the exception handler when the handler is the first one in the call stack whose type matches that of the exception thrown.

> The `writeList` method from the `ListOfNumbers` class uses two exception handlers for its `try` statement, with one handler for each of the two types of exceptions that can be thrown within the `try` block -- `ArrayIndexOutOfBoundsException` and `IOException`.

> >     try {
> >         . . .
> >     } catch (ArrayIndexOutOfBoundsException e) {
> >         System.err.println("Caught ArrayIndexOutOfBoundsException: " +
> >     		        e.getMessage());
> >     } catch (IOException e) {
> >         System.err.println("Caught IOException: " +
> >     		        e.getMessage());
> >     }

> ### Catching Multiple Exception Types with One Handler

> > The two exception handlers used by the `writeList` method are very specialized. Each handles only one type of exception. The Java language allows you to write general exception handlers that handle multiple types of exceptions.

> > As you know, Java exceptions are `Throwable` objects; they are instances of `Throwable` or a subclass of `Throwable`. The Java packages contain numerous classes that derive from `Throwable` and thus, build a hierarchy of `Throwable` classes.

> > Your exception handler can be written to handle any class that inherits from `Throwable`. If you write a handler for a "leaf" class (a class with no subclasses), you've written a specialized handler: it will only handle exceptions of that specific type. If you write a handler for a "node" class (a class with subclasses), you've written a general handler: it will handle any exception whose type is the node class or any of its subclasses.

> > Let's modify the `writeList` method once again. Only this time, let's write it so that it handles both `IOExceptions` and `ArrayIndexOutOfBoundsExceptions`. The closest common ancester of `IOException` and `ArrayIndexOutOfBoundsException` is the `Exception` class. An exception handler that handles both types of exceptions looks like this:

> > >     try {
> > >         . . .
> > >     } catch (Exception e) {
> > >         System.err.println("Exception caught: " + e.getMessage());
> > >     }

> > The class is pretty high in the `Throwable` class hierarchy. So in addition to the `IOException` and `ArrayIndexOutOfBoundsException` types that this exception handler is intended to catch, it will catch numerous other types. Generally speaking, your exception handlers should be more specialized. Handlers that can catch most or all exceptions are typically useless for error recovery because the handler has to determine what type of exception occurred anyway to determine the best recovery strategy. Also, exception handlers that are too general can make code more error prone by catching and handling exceptions that weren't anticipated by the programmer and for which the handler was not intended.

> | Start of Tutorial > Start of Trail > Start of Lesson | Search