A ordem de execução try-catch-finally parece ser aleatória

Eu estou tentando entender como funciona o stream de execução try-catch-finally . Há algumas soluções dos usuários do Stack Overflow em relação ao stream de execução.

Um exemplo é:

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

O código A será executado. Se tudo correr bem (ou seja, nenhuma exceção é lançada enquanto A está sendo executado), ela irá para o finally , então o código C será executado. Se uma exceção é lançada enquanto A é executada, então ela irá para B e, finalmente, para C.

No entanto, recebi diferentes streams de execução quando tentei:

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

Eu estou recebendo duas saídas diferentes:

Primeira saída:

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

No entanto, quando eu corri o mesmo programa pela segunda vez:

Segunda saída:

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

O que devo concluir disso? Vai ser random?

printStackTrace() para o erro padrão. System.out.println("common") enviado para a saída padrão. Ambos são roteados para o mesmo console, mas a ordem em que eles aparecem nesse console não é necessariamente a ordem em que foram executados.

Se você escrever no mesmo stream tanto no bloco catch quanto no bloco finally (por exemplo, tente System.err.println("common") ), verá que o bloco catch sempre é executado antes do bloco finally quando uma exceção é apanhado.

Código-fonte do método printstacktrace() da exceção (definido na class Throwable )

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

A formatação da saída ocorre porque você está usando o stream de saída padrão através de System.out.println e ocorre a exceção System.err stream

Tente ter uma variável que verificará as exceções e imprimirá no mesmo console de erros se ocorrer uma exceção:

 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"); } }