Это может показаться вопросом программирования, и я подумал, что знаю ответ, но теперь мне нужно перепроверить. В этом фрагменте кода ниже будет ли исключение, генерируемое в первом блоке catch, перехватываться общим блоком catch Exception ниже?
try {
// Do something
} catch(IOException e) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}
Я всегда думал, что ответ будет отрицательным, но теперь у меня есть странное поведение, которое может быть вызвано этим. Ответ, вероятно, одинаков для большинства языков, но я работаю на Java.
Ответы:
Нет, поскольку новый
throw
не находится вtry
блоке напрямую.источник
RuntimeException
изcatch
блока выдается a, ошибки компиляции не будет.catch
указано в списке перед дочернимcatch
предложением исключения . Насколько я понимаю, Java запрещает это, и это ловится во время компиляции.Нет, это очень легко проверить.
Следует напечатать:
Технически это могло быть ошибкой компилятора, зависящей от реализации, неопределенным поведением или чем-то еще. Тем не менее, JLS довольно хорошо прибит, и компиляторы достаточно хороши для такого рода простых вещей (случай с обобщенным углом может отличаться).
Также обратите внимание, что если вы поменяете местами два блока catch, он не скомпилируется. Второй улов будет полностью недоступен.
Обратите внимание, что блок finally всегда выполняется, даже если выполняется блок catch (кроме глупых случаев, таких как бесконечные циклы, присоединение через интерфейс инструментов и уничтожение потока, перезапись байт-кода и т. Д.).
источник
finally
это, конечно, позвонитьSystem.exit
. :-Pfor(;;);
короче, содержится в языке, мало что дает в плане побочных эффектов и, для меня, более очевидно.System.exit
более дружественный к процессору! : -O Но да, ладно, это явно субъективный критерий. Кроме того, я не знал, что ты игрок в гольф. ;-)Спецификация языка Java говорит в разделе 14.19.1:
Ссылка: http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#24134
Другими словами, первый включающий улов, который может обработать исключение, делает, и если исключение выбрасывается из этого улова, это не входит в область действия какого-либо другого улова для первоначальной попытки, поэтому они не будут пытаться обработать его.
Одна связанная и запутанная вещь, которую нужно знать, это то, что в структуре try-[catch] -finally блок finally может выдать исключение, и если это так, любое исключение, выброшенное блоком try или catch, будет потеряно. Это может сбить с толку, когда вы впервые увидите это.
источник
try
-with-resources. Затем, еслиtry
ANDfinally
оба throw,finally
подавляется, но также ДОБАВЛЯЕТСЯ в исключение изtry
. Еслиcatch
бросает также, вам не повезло, если вы сами не справитесь с этим с помощью addSuppressed и добавитеtry
исключение - тогда у вас есть все три.Если вы хотите выбросить исключение из блока catch, вы должны сообщить свой метод / класс / и т. Д. что для этого нужно выбросить указанное исключение. Вот так:
И теперь ваш компилятор не будет на вас кричать :)
источник
Нет - как сказал Крис Джестер-Янг, это будет выброшено на следующую попытку в иерархии.
источник
Как сказано выше ...
Я хотел бы добавить, что если у вас возникли проблемы с просмотром происходящего, если вы не можете воспроизвести проблему в отладчике, вы можете добавить трассировку перед повторным вызовом нового исключения (со старой доброй системой .out.println в худшем случае, с хорошей системой журналов, как log4j в противном случае).
источник
Это не будет поймано вторым блоком захвата. Каждое исключение отлавливается только внутри блока try. Вы можете вложить попытки хотя (не то, что это хорошая идея вообще):
источник
Нет, поскольку все перехваты ссылаются на один и тот же блок try, поэтому выброс изнутри блока перехвата будет перехвачен включающим блоком try (возможно, в методе, который вызвал этот)
источник
Старая запись, но переменная "e" должна быть уникальной:
источник