2014-09-30 6 views
1

JLS 8, 14.20:Почему я не могу избежать исключения более одного раза?

попытка оператор выполняет блок. Если значение выбрано, и в заявлении try есть одно или несколько положений catch, которые могут его поймать, тогда управление будет передано на в первый такой пункт catch.

Похоже, что у меня могут быть, например, два предложения catch для одного и того же типа исключения. Но когда я попробую это, я получу ошибку времени компиляции.

public static void main (String[] args) throws java.lang.Exception 
{ 
    try{ 
    } catch(RuntimeException ioe){ 
    } catch(NumberFormatException e){ //Already caught 
    } 
} 

IDEONE

Не могли бы вы объяснить это с помощью JLS?

+0

У вас может быть два, но «Это ошибка времени компиляции, если объединение типов содержит две альтернативы Di и Dj (i ≠ j), где Di является подтипом Dj (§4.10.2).». Если вам нужно, поместите try-catch (NFE) и переверните его, и вокруг него появится try-catch (RE) – Philipp

+0

. В чем смысл одного и того же исключения более одного раза в одном и том же заявлении try? Ошибка компиляции довольно понятна в этом 'unreachable catch block ...'. – A4L

+0

@Philipp У меня здесь есть союз типа? –

ответ

2

NumberFormatException - это специализация RuntimeException, поэтому ваше исключение NumberFormatException будет уже обнаружено первым оператором. Однако вы можете переключить порядок этих двух предложений catch; но имейте в виду только один будет выполняться:

  • оговорка NumberFormatException если исключение имеет этот тип
  • оговорка RuntimeException для всех других типов RuntimeException

Как почему это таким образом ... Ну вот как был разработан язык. Если бы все соответствующие блоки блокировки выполнялись, было бы труднее обрабатывать ошибки правильно.

+0

_Well Вот как язык был разработан. Не могли бы вы предоставить цитату, которая это доказывает? Дизайн языка должен быть полностью описан в спецификации, не так ли? –

+0

В той части спецификации, которую вы указали в своем вопросе, точно сказано следующее: выполняется первое предложение catch, которое соответствует исключению, что означает, что выполняется только одно соответствующее предложение catch. Что касается спецификации, в которой говорится, почему вы не можете писать предложения catch в порядке, указанном в вашем вопросе, это другой вопрос (возможно, написанный где-то еще) – personne3000

+0

http://docs.oracle.com/javase/specs/jls/se8/html /jls-11.html#jls-11.2.3: «Это ошибка времени компиляции, если предложение catch может поймать класс исключений E1, и предыдущее предложение catch сразу включающего оператора try может поймать E1 или суперкласс E1 «. Edit: заметил, что он был отправлен ранее Seelenvirtuose в качестве комментария к вашему вопросу – personne3000

1

Поскольку RunTimeException является базовым классом исключения NumberFormatException. http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html

+0

Да, я знаю. Я спрашиваю, почему мы не можем поймать одно и то же исключение два или более раза? –

+0

Это потому, что в спецификации указано «первое» предложение catch. – LastFreeNickname

1

Ошибка компилятора, полученная из иерархии исключенных захватов.

NumberFormatException extends IllegalArgumentException extends RuntimeException

Think сточного блока в качестве социальной защиты. Сеть NumberFormatException - довольно маленькая, так как это особый случай исключений высшей иерархии. Сеть RuntimeException является одним из максимально возможного и будет захватывать что-либо на этом уровне (кроме Exception и Throwables, которые являются «превосходными»). То, что вы сделали, - . Поместите небольшую сетку ниже большой сетки. Поэтому компилятор достаточно вежлив, чтобы дать вам подсказку о том, что меньшая сеть никогда не будет достигнута.

(я знаю, что metapher не 100% точная, но в этом контексте работает отлично.)

Если вы ловите NumberFormatException первым, а затем RuntimeException компилятор с удовольствием согласен! :-) Вы также можете сбросить свое пойманное исключение из первого блока.

1

NumberFormatException является суб тип RuntimeException Когда вы поймали RuntimeException, он будет пойман всех типов RuntimeException включая NumberFormatException. Вот почему он уже пойман.

Смежные вопросы