Почему функция multi-catch в Java требует, чтобы исключения были окончательными?

Документация Oracle по функции multi-catch, добавленной в Java 7, гласит, что параметр исключения в catch пункт неявно final,

Мой вопрос: в чем смысл такого ограничения? Потому что я не могу найти ни одного существенного улучшения, которое оно приносит. Маркировка ссылочного объекта как final только защищает саму ссылку от изменения, а не объект, на который она ссылается, и никогда не запрещается создавать другую ссылку и изменять ее так, как они захотят.

Несколько актуальный вопрос о SO обсуждает причины, по которым изменение ссылки на исключение в catch это не самая мудрая вещь, но она касается любого использования catch пункт, а не только его мульти-улов. Так почему же Java делает исключение для multi-catch и обрабатывает его особым образом?

Спасибо!

1 ответ

Решение

В предложении uni-catch вы можете переназначить объект исключения. Например, это прекрасно работает:

try {
    ... // code that can throw IOException or some user-defined ParserException
} catch(IOException) {
    e = new IOException();  // this is acceptable (although there is no point in doing it)
    e.printStackTrace();
}

Компилятор точно знает, что брошенный объект имеет тип IOException, Однако в предложении multi-catch вы можете получить что-то вроде:

try {
    ... // code that can throw IOException or some user-defined ParserException
} catch(IOException | ParserException e) {
    e = new IOException(); // this is NOT acceptable -- e may reference a ParserException
    e.printStackTrace();
}

В этом случае компилятор не знает, какой тип исключения находится во время компиляции, поэтому присваивает новый IOException к переменной, которая может ссылаться либо на IOException или же ParseException не должно быть позволено К этому следует добавить отсутствие сценариев использования для назначения переменной исключения. Поэтому имеет смысл сделать переменную неявно final и избежать всего этого беспорядка. Если вам действительно нужно присвоить переменную, вы можете переключиться на старый способ записи последовательности catch блоки.

Другие вопросы по тегам