Uncaught RuntimeException и finally clause: что на первом месте?
A RuntimeException
помещается в блок try
без захвата, а предложение finally
вызывает System.exit()
.
public static void main(String[] args) {
try {
Integer.valueOf("NotANumber");
} finally {
System.out.println("finally");
System.exit(0);
}
}
Выходной сигнал
finally
Если System.exit(0)
удаляется, наконец, вывод
finally
Exception in thread "main" java.lang.NumberFormatException: For input string: "NotANumber"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.valueOf(Integer.java:554)
at exception.MyExcepTest.main(MyExcepTest.java:20)
Где "наконец" может появляться до, после или между мешанием NumberFormatException
.
Может кто-нибудь объяснить это?
Ответы
Ответ 1
Окончательный блок, безусловно, будет выполнен до выхода основного метода, и после этого будет выведено значение stacktrace из JVM.
Может быть, stacktrace будет напечатано в System.err, и два потока будут перемешаться на вашем консольном выходе непредсказуемыми способами (поскольку они создаются в основном одновременно).
Что происходит, когда вы также печатаете "наконец" в System.err?
Ответ 2
Дело в том, что когда возникает исключение. JVM 1st выполняет код с внутренним окончательным блоком, а затем генерирует исключение, если он пойман, или он будет генерировать исключение и прекратить поток.
поэтому здесь, когда System.exit(0) присутствует в блоке finally, он немедленно прекращает поток, поэтому JVM не получает шанс выбросить исключение.
поэтому выход - это просто "наконец"
Ответ 3
Наконец, блок выполняется всегда. Это гарантируется языком. Он выполняется, если вы пытаетесь выполнить блокировку, завершается успешно или генерируется какое-либо исключение.
Исключены проверенные и непроверенные исключения. Для неконтролируемых исключений (Runtime and Errors) вам не нужно писать блок catch. Но все исключения попадают в JVM, который печатает стек. Когда ваш окончательный блок завершает работу приложения, у него нет возможности распечатать stacktrace, поэтому вы его не видите.
Как правило, выход из программы в конечном блоке плохой, потому что он выйдет, даже если ваш код работает успешно. И в целом, наконец, блок обычно необходим для очистки, например, закрытия файлов, сокетов и т.д., А не для более сложной бизнес-логики.
Ответ 4
есть два блока, которые мы можем использовать с try, это catch и, наконец,
Блок блокировки выполняется, когда генерируется какое-либо исключение RunTime (до окончательного), и, наконец, блок выполняется в конце, независимо от исключения, или нет.
поэтому, если вы хотите что-то сделать, если вы выбрали исключение, вы можете поместить это в catch (Excepion e).
И что вы видите, это обязанность JVM выполнять то, что когда-либо было написано в блоке finally до завершения выполнения программы.
И когда программа завершается, по умолчанию отображается трассировка созданного исключения.
Ответ 5
Наконец, метод всегда будет выполняться даже в случае оператора return в блоке try, но в некоторых случаях, когда металирование ошибок (Run time memory) в блоке try не гарантируется, окончательный блок выполняется полностью.
В вашем случае, наконец, блок всегда выполняется, а исключение вызывается основным методом из JVM, поскольку вы не обрабатываете исключение.