Оператор try выполняет блок. Если значение выбрано, и оператор try имеет одно или несколько кластеров catch, которые могут его поймать, тогда управление будет передано в первое предложение catch.
Похоже, у меня могут быть, например, два предложения catch для одного и того же типа исключения. Но когда я попробую это, я получу ошибку времени компиляции.
public static void main (String[] args) throws java.lang.Exception
{
try{
} catch(RuntimeException ioe){
} catch(NumberFormatException e){ //Already caught
}
}
Не могли бы вы объяснить это с помощью JLS?
NumberFormatException - это специализация RuntimeException, поэтому ваше исключение NumberFormatException будет уже захвачено первым оператором. Однако вы можете переключить порядок этих двух предложений catch; но имейте в виду, что только один будет выполнен:
Что касается того, почему именно так... Ну вот как был разработан язык. Если бы все соответствующие блоки блокировки выполнялись, было бы труднее обрабатывать ошибки правильно.
NumberFormatException
- это подтип RuntimeException
Когда вы поймали RuntimeException
, он поймает все типы RuntimeException
включая NumberFormatException
. Вот почему он говорит, что уже пойман.
Ошибка компилятора вы получаете результаты из иерархии исключенных исключений.
NumberFormatException extends IllegalArgumentException extends RuntimeException
Подумайте о блоке захвата в качестве систем безопасности. Сеть NumberFormatException довольно мала, так как это особый случай высших исключений иерархии. Сеть RuntimeException является одной из самых больших и будет захватывать что-либо на этом уровне (кроме Exception и Throwables, которые являются "превосходящими"). То, что вы сделали, это разместить небольшую сеть ниже большой сети. Поэтому компилятор достаточно вежлив, чтобы дать вам подсказку о том, что меньшая сеть никогда не будет достигнута.
(Я знаю, что метафар не на 100% точнее, но в этом контексте отлично работает.)
Если вы сначала поймаете NumberFormatException, а затем RuntimeException, компилятор с радостью согласится! :-) Вы также можете перебросить пойманное исключение из первого блока.
Поскольку RunTimeException является базовым классом NumberFormatException. http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html
It is a compile-time error if a union of types contains two alternatives Di and Dj (i ≠ j) where Di is a subtype of Dj (§4.10.2).
, Если вам нужно, поместите try-catch (NFE) и перебросьте его, а вокруг этого поставьте try-catch (RE)unreachable catch block ...