Вот простой пример использования исключения:
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
Поскольку исключения не могут быть параметрическими, синтаксис ограничен, поэтому тип должен
записываться как идентификатор без следующего параметра.