Порядок выполнения 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");
}
}