6.3. Exception HandlingIn a try statement, each catch clause checks whether the thrown exception matches a given type. This is the same as the check performed by an instance test, so the same restriction applies: the type must be reifiable. Further, the type in a catch clause is required to be a subclass of THRowable. Since there is little point in creating a subclass of THRowable that cannot appear in a catch clause, the Java compiler complains if you attempt to create a parameterized subclass of THRowable. For example, here is a permissible definition of a new exception, which contains an integer value: class IntegerException extends Exception { private final int value; public IntegerException(int value) { this.value = value; } public int getValue() { return value; } } And here is a simple example of how to use the exception: class IntegerExceptionTest { public static void main(String[] args) { try { throw new IntegerException(42); } catch (IntegerException e) { assert e.getValue() == 42; } } } The body of the TRy statement throws the exception with a given value, which is caught by the catch clause. In contrast, the following definition of a new exception is prohibited, because it creates a parameterized type: class ParametricException<T> extends Exception { // compile-time error private final T value; public ParametricException(T value) { this.value = value; } public T getValue() { return value; } } An attempt to compile the above reports an error: % javac ParametricException.java ParametricException.java:1: a generic class may not extend java.lang.Throwable class ParametricException<T> extends Exception { // compile-time error ^ 1 error This restriction is sensible because almost any attempt to catch such an exception must fail, because the type is not reifiable. One might expect a typical use of the exception to be something like the following: class ParametricExceptionTest { public static void main(String[] args) { try { throw new ParametricException<Integer>(42); } catch (ParametricException<Integer> e) { // compile-time error assert e.getValue()==42; } } } This is not permitted, because the type in the catch clause is not reifiable. At the time of this writing, the Sun compiler reports a cascade of syntax errors in such a case: % javac ParametricExceptionTest.java ParametricExceptionTest.java:5: <identifier> expected } catch (ParametricException<Integer> e) { ^ ParametricExceptionTest.java:8: ')' expected } ^ ParametricExceptionTest.java:9: '}' expected } ^ 3 errors Because exceptions cannot be parametric, the syntax is restricted so that the type must be written as an identifier, with no following parameter. Type Variable in a Throws Clause Although subclasses of THRowable cannot be parametric, it is possible to use a type variable in the throws clause of a method declaration. This technique is illustrated in Section 9.3. |