Вот простой пример того, как использовать исключение:
class IntegerExceptionTest {
public static void main(String[] args) {
try {
throw new IntegerException(42);
} catch (IntegerException e) {
assert e.getValue() == 42;
}
}
}
Тело оператора TRy выдает исключение с заданным значением, которое перехватывается предложением catch.
Напротив, следующее определение нового исключения запрещено, поскольку оно создает параметризованный тип:
class ParametricException<T> extends Exception { // compile-time error
private final T value;
public ParametricException(T value) { this.value = value; }
public T getValue() { return value; }
}
Попытка скомпилировать вышесказанное сообщает об ошибке:
% 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
Это ограничение имеет смысл, потому что почти любая попытка поймать такое исключение должна потерпеть неудачу, потому что тип не может быть переопределен. Можно ожидать, что типичное использование исключения будет выглядеть примерно так:
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;
}
}
}
Это недопустимо, потому что тип в предложении catch не является пригодным для повторного использования. На момент написания этой статьи компилятор Sun сообщал о каскаде синтаксических ошибок в таком случае:
% javac ParametricExceptionTest.java
ParametricExceptionTest.java:5: <identifier> expected
} catch (ParametricException<Integer> e) {
^
ParametricExceptionTest.java:8: ')' expected
}
^
ParametricExceptionTest.java:9: '}' expected
}
^
3 errors
Поскольку исключения не могут быть параметрическими, синтаксис ограничен, поэтому тип должен быть записан как идентификатор без следующего параметра.