2014-05-22 3 views
8

Мой вопрос связан с синтаксической поведение блока попытка пойматьЛовить исключения, которые не выбрасываются локально?

Empty попробовать блок с уловом, как этот

void fun() { 
    try {} 
    catch(Exception e) {} 
} 

или

try {} 
catch(ArrayIndexOutOfBoundsException e) {} 

компилирует, но компилятор жалуется

try {} 
catch(IOException e) {} 

Почему компилятор всего ow ловит все, что имеет тип Exception или RuntimeException, тогда как оно жалуется на недостижимый код с проверенными исключениями? Это потому, что код JVM может вызывать эти типы? Как может JVM возможно выбросить ArrayIndexOutOfBoundsException в пустой блок try?

ответ

10

Пустой блок - это специальный чехол, который специально не обрабатывается JLS. Что делает JLS , так это то, что если вы поймаете проверенное исключение, код в блоке try должен был бы выкинуть это исключение (то есть он бросил его прямо или вызвал метод, который был объявлен, возможно, его бросил) ,

Другими словами, существует проверка на чистоту специально для отмеченных исключений, но не для всех исключений с проверенными исключениями, получающих дополнительное внимание.

Это описано в JLS 14.21, а именно:

Это ошибка времени компиляции, если оператор не может быть выполнено, так как он недоступен.

...

Блок улова C доступен тогда и только тогда оба из следующих условий:

  • Либо тип параметра C «ы это непроверенный тип исключения или Exception или суперкласс Exception, или какое-либо выражение или выражение throw в блоке try доступно и может вызывать проверенное исключение, тип которого можно присвоить типу параметра C. (Выражение доступно, если внутреннее утверждение, содержащее его, доступно.)

    См. §15.6 для нормального и резкого завершения выражений.

  • Там не ранее блок A поймать в заявлении попробовать такие, что тип C «параметра s такой же, как и подкласс типа A» параметра s.

Выделено: это показывает, что если вы подхватить непроверенный тип исключения, блок поймать достижим.

Я лично считаю формулировку несколько запутанной.Слегка перефразировать, то первая точка пули как раз говорит о том, что пункт улов должен поймать одного из:

  • непроверенный Exception
  • Exception
  • Throwable (который является единственным суперкласс Exception кроме Object, которые вы можете «т улова)
  • проверяемого исключения, что try блока может бросить

второго бул пусть защита от блока catch недостижима из-за предыдущего catch в том, что try. Например:

try { 
    whatever(); 
} catch (Exception e) { 
    handleException(e); 
} catch (NullPointerException e) { 
    // This block is unreachable, because a NullPointerException is an 
    // Exception and will thus be handled by the previous catch block. 
    handleNpe(e); 
} 
Смежные вопросы