Порядок выполнения try-catch-finally представляется случайным

Я пытаюсь понять, как работает поток выполнения try-catch-finally. Существует несколько решений от пользователей Qaru относительно их потока выполнения.

Один из таких примеров:

try {
    // ... some code: A
} 
catch(...) {
    // ... exception code: B
} 
finally {
    // finally code: C
}

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

Однако, когда я попробовал, у меня были разные потоки выполнения:

try {
    int a=4;
    int b=0;
    int c=a/b;
}
catch (Exception ex)
{
    ex.printStackTrace();
}
finally {
    System.out.println("common");
}

Я получаю два разных выхода:

Первый вывод:

java.lang.ArithmeticException: / by zero
at substrings.main(substrings.java:15)
lication.AppMain.main(AppMain.java:140)
common

Однако, когда я запускал ту же программу во второй раз:

Второй вывод:

 common
    java.lang.ArithmeticException: / by zero
    at substrings.main(substrings.java:15)

Что я должен сделать из этого? Будет ли это случайным?

Ответы

Ответ 1

printStackTrace() выводится на стандартную ошибку. System.out.println("common") выводится на стандартный вывод. Оба они маршрутизируются на ту же консоль, но порядок, в котором они отображаются на этой консоли, не обязательно является порядком, в котором они были выполнены.

Если вы пишете в один поток в обоих блоках catch и, наконец, блокируете (например, попробуйте System.err.println("common")), вы увидите, что блок catch всегда выполняется перед блоком finally, когда исключение поймано.

Ответ 2

Исключение printstacktrace() метод исходный код (определенный в классе Throwable)

public void printStackTrace() {
        printStackTrace(System.err);
    }

Форматирование вывода происходит из-за того, что вы используете стандартный выходной поток через System.out.println и возникает исключение System.err stream

Попробуйте иметь переменную, которая будет проверять исключения и печатать в той же самой консоли ошибок, если возникает исключение: -

boolean isException = false;
try {
        int a=4;
        int b=0;
        int c=a/b;
    }
    catch (Exception ex)
    {
       isException = true
       ex.printStackTrace();
    }
    finally {
       if(isException){
        System.err.println("common");
       }else{
        System.out.println("common");
       }
  }