Posted on Leave a comment

The catch Clause – Exception Handling

The catch Clause

Only an exit from a try block resulting from an exception can transfer control to a catch clause. A catch clause can catch the thrown exception only if the exception is assignable to the parameter in the catch clause. The code of the first such catch clause is executed, and all other catch clauses are ignored.

On exit from a catch clause, normal execution continues unless there is any uncaught exception that has been thrown and not handled. If this is the case, the method is aborted after the execution of any finally clause and the exception propagated up the JVM stack.

It is important to note that after a catch clause has been executed, control is always transferred to the finally clause if one is specified. This is true as long as there is a finally clause, regardless of whether the catch clause itself throws an exception.

In Example 7.2, the method printAverage() calls the method computeAverage() in a try-catch construct at (4). The catch clause is declared to catch exceptions of type ArithmeticException. The catch clause handles the exception by printing the stack trace and some additional information at (7) and (8), respectively. Normal execution of the program is illustrated in Figure 7.5, which shows that the try block is executed but no exceptions are thrown, with normal execution continuing after the try-catch construct. This corresponds to Scenario 1 in Figure 7.4.

Figure 7.5 Exception Handling (Scenario 1)

Example 7.2 The try-catch Construct

Click here to view code image

public class Average2 {
  public static void main(String[] args) {
    printAverage(100, 20);                                         // (1)
    System.out.println(“Exit main().”);                            // (2)
  }
  public static void printAverage(int totalSum, int totalCount) {
    try {                                                          // (3)
      int average = computeAverage(totalSum, totalCount);          // (4)
      System.out.println(“Average = ” +                            // (5)
          totalSum + ” / ” + totalCount + ” = ” + average);
    } catch (ArithmeticException ae) {                             // (6)
      ae.printStackTrace();                                        // (7)
      System.out.println(“Exception handled in printAverage().”);  // (8)
    }
    System.out.println(“Exit printAverage().”);                    // (9)
  }
public static int computeAverage(int sum, int count) {
    System.out.println(“Computing average.”);                      // (10)
    return sum/count;                                              // (11)
  }
}

Output from the program, with call printAverage(100, 20) at (1):

Computing average.
Average = 100 / 20 = 5
Exit printAverage().
Exit main().

Output from the program, with call printAverage(100, 0) at (1):

Click here to view code image

Computing average.
java.lang.ArithmeticException: / by zero
        at Average2.computeAverage(Average2.java:23)
        at Average2.printAverage(Average2.java:11)
        at Average2.main(Average2.java:5)
Exception handled in printAverage().
Exit printAverage().
Exit main().

However, if we run the program in Example 7.2 with the following call at (1):

printAverage(100, 0)

an ArithmeticException is thrown by the integer division operator in the method computeAverage(). In Figure 7.6 we see that the execution of the method compute-Average() is stopped and the exception propagated to method printAverage(), where it is handled by the catch clause at (6). Normal execution of the method continues at (9) after the try-catch construct, as witnessed by the output from the statements at (9) and (2). This corresponds to Scenario 2 in Figure 7.4.

In Example 7.3, the main() method calls the printAverage() method in a try-catch construct at (1). The catch clause at (3) is declared to catch exceptions of type ArithmeticException. The printAverage() method calls the computeAverage() method in a try-catch construct at (7), but here the catch clause is declared to catch exceptions of type IllegalArgumentException. Execution of the program is illustrated in Figure 7.7, which shows that the ArithmeticException is first propagated to the catch clause in the printAverage() method. Because this catch clause cannot handle this exception, it is propagated further to the catch clause in the main() method, where it is caught and handled. Normal execution continues at (6) after the exception is handled.

In Example 7.3, the execution of the try block at (7) in the printAverage() method is never completed: The statement at (9) is never executed. The catch clause at (10) is skipped. The execution of the printAverage() method is aborted: The statement at (13) is never executed, and the exception is propagated. This corresponds to Scenario 3 in Figure 7.4.

Figure 7.6 Exception Handling (Scenario 2)

Example 7.3 Exception Propagation

Click here to view code image

public class Average3 {
  public static void main(String[] args) {
    try {                                                          // (1)
      printAverage(100, 0);                                        // (2)
    } catch (ArithmeticException ae) {                             // (3)
      ae.printStackTrace();                                        // (4)
      System.out.println(“Exception handled in main().”);          // (5)
    }
    System.out.println(“Exit main().”);                            // (6)
  }
  public static void printAverage(int totalSum, int totalCount) {
    try {                                                          // (7)
      int average = computeAverage(totalSum, totalCount);          // (8)
      System.out.println(“Average = ” +                            // (9)
totalSum + ” / ” + totalCount + ” = ” + average);
    } catch (IllegalArgumentException iae) {                       // (10)
      iae.printStackTrace();                                       // (11)
      System.out.println(“Exception handled in printAverage().”);  // (12)
    }
    System.out.println(“Exit printAverage().”);                    // (13)
  }
  public static int computeAverage(int sum, int count) {
    System.out.println(“Computing average.”);                      // (14)
    return sum/count;                                              // (15)
  }
}

Output from the program:

Click here to view code image

Computing average.
java.lang.ArithmeticException: / by zero
        at Average3.computeAverage(Average3.java:28)
        at Average3.printAverage(Average3.java:16)
        at Average3.main(Average3.java:6)
Exception handled in main().
Exit main().

The scope of the exception parameter name in the catch clause is the body of the catch clause—that is, it is a local variable in the body of the catch clause. As mentioned earlier, the type of the exception object must be assignable to the type of the argument in the catch clause. In the body of the catch clause, the exception object can be queried like any other object by using the parameter name.

The javac compiler complains if a catch clause for a superclass exception shadows the catch clause for a subclass exception, as the catch clause of the subclass exception will never be executed (a situation known as unreachable code). The following example shows incorrect order of the catch clauses at (1) and (2), which will result in a compile-time error at (2): The superclass Exception will shadow the subclass ArithmeticException.

Click here to view code image

try {
  // …
} catch (Exception e) {              // (1) Superclass shadows subclass
  System.out.println(e);
} catch (ArithmeticException e) {    // (2) Compile-time error: Unreachable code
  System.out.println(e);
}

The compiler will also flag an error if the parameter of the catch clause has a checked exception type that cannot be thrown by the try block, as this would result in unreachable code.

Click here to view code image

try {
  throw new ArithmeticException();      // IOException never thrown in try block
} catch (IOException e) {               // Compile-time error: Unreachable code
  System.out.println(e);
}

Figure 7.7 Exception Handling (Scenario 3)

Leave a Reply

Your email address will not be published. Required fields are marked *