2015-10-17 11 views
15

Sto cercando di capire come funziona il flusso di esecuzione try-catch-finally. Ci sono un paio di soluzioni dagli utenti di Stack Overflow riguardo al loro flusso di esecuzione.L'ordine di esecuzione try-catch-finally sembra essere casuale

Un esempio è:

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

Codice A sta per essere giustiziato. Se tutto va bene (cioè nessuna eccezione viene generata mentre A è in esecuzione), andrà a finally, quindi il codice C sta per essere eseguito. Se viene generata un'eccezione mentre A viene eseguito, quindi andrà a B e infine a C.

Tuttavia, mi sono diversi flussi di esecuzione quando l'ho provato:

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

io sono sempre due uscite differenti:

Prima uscita:

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

Carn ehm, quando mi sono imbattuto lo stesso programma per la seconda volta:

Seconda uscita:

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

Cosa devo concludere da questo? Sarà casuale?

+4

Qualunque sia il risultato, ma non dovrebbe essere casuale. Controllo incrociato. –

+1

diversi flussi di sistema produce un'output formattato in modo errato –

+1

Si è tentato di collegare un debugger e di eseguire il codice? – iceman

risposta

42

printStackTrace() uscite a errore standard. System.out.println("common") uscite su uscita standard. Entrambi vengono instradati alla stessa console, ma l'ordine in cui appaiono su quella console non è necessariamente l'ordine in cui sono stati eseguiti.

Se si scrive nello stesso flusso sia in blocco di blocco che in blocco (ad esempio, prova System.err.println("common")), il blocco di cattura viene sempre eseguito prima del blocco finally quando viene rilevata un'eccezione.

7

printstacktrace() metodo codice sorgente di eccezione (definito in Throwable classe)

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

La formattazione dell'output si verifica perché si sta usando flusso di output standard attraverso System.out.println e si verifica un'eccezione System.err flusso

provare ad avere un variabile che controlla le eccezioni e stampa nella stessa console di errore se si verifica un'eccezione: -

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