next up previous
Next: 1.13.3 Exception Handling Up: 1.13 Unusual Situations versus Previous: 1.13.1 A Motivating Example

1.13.2 Using Java Exceptions

A Java exception is an object of type Exception, which is a built-in Java class. There are two basic forms of exceptions that can occur during Java program execution:

1.
Unchecked exceptions, which extend the class RuntimeException, usually signal a program coding error.
2.
Checked exceptions, which extend the class Exception but not the class RuntimeException, signal unusual but legal conditions that require deviation from the normal flow of control.

When an EvalVisitor encounters a Var not bound in Env, it has detected an error in the input expression. If the Arithmetic Expression evaluator is being used in a larger program that can prompt the user for corrected input, then such an input error should be handled as part of valid program execution. It does not indicate a coding error in the Arithmetic Expression evaluator. Hence, when an EvalVisitor encounters an unbound exception, it should throw a checked exception, which the larger program can intercept and interpret, printing an error message such as

I'm sorry, that's not a valid expression
and prompt the user for corrected input with a message like
Please enter a valid expression:

Java requires an explicit throws clause in the header for any method that can generate a checked exception, directly or indirectly by invoking another method. The EvalVisitor class defined above will return null or generate a

NullPointerException
if it encounters an unbound variable. The lookup method will return null as the value of an unbound variable. Any subsequent attempt to use such a value as a Const (e.g., in computing a Sum) will generate a
NullPointerException
. Since this exception is unchecked, it does not need to be declared in throw clauses.

If we rewrite lookup to throw a checked UnboundException instead of returning null, the change has a dramatic impact on the rest of the program. The revised code appears below:

class UnboundException extends Exception {
  UnboundException(String name) {
    super("Variable " + name + " is unbound");
    String varName = name;
  }
}

class Env {
  abstract Const lookup(String name) throws UnboundException};
}

class Empty extends Env {
  Const lookup(String name) throws UnboundException} {
    throw UnboundException(name);
  }
}

class Cons extends Env {
  String firstName;
  Const firstVal;
  Env rest;

  Cons(String name, Const val, Env env) {
    firstName = name;
    firstVal = val;
    rest = env;
  }

  Const lookup(String name) throws UnboundException} {
    if (name.equals(firstName)) return firstVal;
    else return rest.lookup(name);
  }
}

class EvalVisitor implements Visitor {
  Env env;
  Object forConst(Const c) { return c; }
  Object forSum(Sum s) throws UnboundException { ... };
  Object forProd(Prod p) throws UnboundException { ... };
  Object forVar(Var v) throws UnboundException { ... };
  Object forLet(Let l) throws UnboundException { ... };
  }
}

interface Visitor {
  Object forConst(Const c) { return c; }
  Object forSum(Sum s) throws UnboundException;
  Object forProd(Prod p) throws UnboundException;
  Object forVar(Var v) throws UnboundException;
  Object forLet(Let l) throws UnboundException;
}

The preceding code cleanly handles input errors, but it pollutes the signatures of nearly all of the for methods in the class Visitor and its descendants. In this case, an unchecked exception is preferable. The code for this variation is identical the code above except for the extends clause in the definition of class UnboundException and the elimination of all throws clauses in for methods.

Checked exceptions and polymorphic programming do not mix well. Consequently, it should not be surprising that the Java libraries use unchecked exceptions far more than they use checked exceptions. Our advice is use checked exceptions to signal unusual conditions in code that does not involve polymorphism. If polymorphism is present, use unchecked exceptions instead.


next up previous
Next: 1.13.3 Exception Handling Up: 1.13 Unusual Situations versus Previous: 1.13.1 A Motivating Example
Corky Cartwright
2000-01-07