Uncaught RuntimeException и, наконец, предложение: что будет первым? - PullRequest
12 голосов
/ 24 ноября 2011

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.

Кто-нибудь может это объяснить?

Ответы [ 5 ]

15 голосов
/ 24 ноября 2011

Блок finally обязательно будет выполнен до выхода из основного метода, и JVM после этого напечатает трассировку стека.

Возможно, трассировка стека будет напечатана в System.err, и два потока смешаютсяв вашей консоли выводится непредсказуемым образом (поскольку они создаются в основном одновременно).

Что происходит, когда вы печатаете "finally" и в System.err?

6 голосов
/ 24 ноября 2011

Дело в том, что когда выдается исключение. 1-й исполняемый код JVM с внутренним блоком finally, а затем выдает исключение, если оно перехвачено, или оно сгенерирует исключение и завершит поток. поэтому здесь, когда System.exit (0) присутствует в блоке finally, он немедленно завершает поток, поэтому у JVM нет шансов выдать исключение. так что выход положен только "наконец «

3 голосов
/ 24 ноября 2011

Наконец, блок выполняется всегда.Это гарантировано языком.Это выполняется, если вы пытаетесь блокировать успешно завершен или если выдается какое-либо исключение.

Есть проверенные и непроверенные исключения.Для непроверенных исключений (время выполнения и ошибки) вам не нужно писать блок catch.Но все исключения перехватываются JVM, который печатает трассировку стека.Когда ваш блок finally завершает приложение, у него нет возможности распечатать трассировку стека, поэтому вы его не видите.

Обычно выход из программы в блоке finally плох, поскольку он завершится, даже если ваш код успешно выполнен.И, в общем, блок finally, как правило, необходим для очистки, такой как закрытие файлов, сокетов и т. Д., А не для более сложной бизнес-логики.

1 голос
/ 24 ноября 2011

есть два блока, которые мы можем использовать с try, которые являются catch и finally.

блок catch выполняется, когда выбрасывается любое исключение RunTime (до finally), и в конце выполняется блок finally, независимо отисключение выдается или нет.

, поэтому, если вы хотите что-то сделать при возникновении исключения, вы можете поместить это в блок catch (Excepion e).

И что вы видите, это обязанностьJVM для выполнения того, что когда-либо было записано в блоке finally, прежде чем завершить выполнение программы.

И когда программа завершается, по умолчанию отображается трассировка исключительной ситуации.

0 голосов
/ 21 июня 2017

Метод finally всегда будет выполняться даже в случае оператора return в блоке try, но в некоторых случаях, когда выбрасывание ошибок (память времени выполнения) в блок try не гарантирует, что блок finally полностью выполнен.

В вашем случае, блок finally всегда выполняется, и исключение генерируется методом main из JVM, поскольку вы не обрабатываете исключение.

...