10.4 Handling Exceptions Within a Program Exception Propagation: Searching for a Catch Block

Trying, Throwing, and Catching an Exception

In Java, errors and other abnormal conditions are handled by throwing and catching exceptions. When an error or an exceptional condition is detected, you can throw an exception as a way of signaling the abnormal condition. This is like pulling the fire alarm. When an exception is thrown, an exception handler will catch the exception and deal with it (Fig. 10.6). We will discuss try blocks, which typically are associated with catching exceptions, later in the section. 

Annotation 2020-03-29 164146

If we go back to our avgFirstN() example, the typical way of handling this error in Java would be to throw an exception in the avgFirstN() method and catch it in the calling method. Of course, the calling method could be in the same object or it could belong to some other object. In the latter case, the detection of the error is separated from its handling. This division of labor opens up a wide range of possibilities. For example, a program could dedicate a single object to serve as the handler for all its exceptions. The object would be sort of like the program’s fire department.

To illustrate Java’s try/throw/catch mechanism, let’s revisit the CalcAvgTest program. The version shown in Figure 10.7 mimics the way Java’s default exception handler works. If the avgFirstN() method is called with an argument that is zero or negative, an IllegalArgumentException is thrown. The exception is caught by the catch clause in the CalcAvgTest.main() method.

Annotation 2020-03-29 164420

Let’s go through this example step by step. The first thing to notice is that if the CalcAverage.avgFirstN() method has a zero or negative argument, it will throw an exception:

Annotation 2020-03-29 164547

Note the syntax of the throw statement. It creates a new IllegalArgumentException object and passes it a message that describes the error. This message becomes part of the exception object. It can be retrieved using the getMessage() method, which is inherited from the Throwable class (Fig. 10.4).

When a throw statement is executed, the JVM interrupts the normal execution of the program and searches for an exception handler. We will describe the details of this search shortly. In this case, the exception handler is the catch clause contained in the CalcAvgTest.main() method:

Annotation 2020-03-29 164707

When an IllegalArgumentException is thrown, the statements within this catch clause are executed. The first statement uses the getMessage() method to print a copy of the error message. The second statement uses the printStackTrace() method, which is defined in Throwable and inherited by all Exceptions, to print a trace of the method calls leading up to the exception. The last statement causes the program to terminate.

When we run this program, the following output will be generated as a result of the illegal argument error:

Annotation 2020-03-29 164827

Thus, as in the previous example of Java’s default exception handler, our exception handler also prints out a description of the error and a trace of the method calls that led up to the error. However, in this example, we are directly handling the exception rather than leaving it up to Java’s default exception handler. Of course, this example is intended mainly for illustrative purposes. It would make little sense to write our own exception handler if it does nothing more than mimic Java’s default handler.

Annotation 2020-03-29 164926

Finally, note that the catch clause is associated with a try block. The handling of exceptions in Java takes place in two parts: First, we try to execute some statements, which may or may not lead to an exception. These are the statements contained within the try clause:

Annotation 2020-03-29 165031

Second, we provide one or more catch clauses to handle particular types of exceptions. In this case, we are only handling IllegalArgumentExceptions.

As we said earlier, throwing an exception is like pulling a fire alarm. The throw occurs somewhere within the scope of the try block. The “fire department” in this case is the code contained in the catch clause that immediately follows the try block. This is the exception handler for this particular exception. There’s something like a game of catch going on here: Some method within the try block throws an Exception object, which is caught and handled by the catch block located in some other object (Fig. 10.8).

Annotation 2020-03-29 165219