2015-10-17 18 views
15

Próbuję zrozumieć, jak działa przepływ zadań try-catch-finally. Istnieje kilka rozwiązań od użytkowników Stack Overflow dotyczących ich przepływu wykonania.Ostateczna kolejność wykonywania poleceń wydaje się być losowa.

Jednym z takich przykładów jest:

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

kod A ma być wykonana. Jeśli wszystko pójdzie dobrze (to znaczy nie zostaną wysłane żadne wyjątki podczas wykonywania A), przejdzie ono do finally, więc kod C zostanie wykonany. Jeśli jest wyjątek, podczas gdy jest wykonywany, a następnie przejdzie do B, a następnie w końcu do C.

Jednak mam inny wykonanie przepływa gdy próbowałem go:

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

Dostaję dwa różne wyjścia:

Najpierw wyjściowe:

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

Howev er, kiedy prowadził ten sam program po raz drugi:

Drugie wyjście:

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

Co mam z tego wywnioskować? Czy to będzie losowe?

+4

Jakikolwiek wynik, ale nie powinien być losowy. Sprawdź krzyż. –

+1

Różne strumienie systemowe produkują nieprawidłowo sformatowane wyjście. –

+1

Czy próbowałeś dołączyć debugger i przejść przez kod? – iceman

Odpowiedz

42

printStackTrace() wyjścia do błędu standardowego. System.out.println("common") wyjścia do standardowego wyjścia. Oba są kierowane do tej samej konsoli, ale kolejność, w jakiej pojawiają się na tej konsoli, niekoniecznie jest kolejnością, w jakiej zostały wykonane.

Jeśli napiszesz do tego samego strumienia w bloku catch i na końcu bloku (na przykład spróbuj System.err.println("common")), zobaczysz, że blok catch jest zawsze wykonywany przed blokiem finally, gdy zostanie przechwycony wyjątek.

7

printstacktrace() metoda kod źródłowy Wyjątkiem jest (zdefiniowane w Throwable klasy)

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

Formatowanie wyjściu występuje, ponieważ są za pomocą standardowego strumienia wyjściowego poprzez System.out.println i wyjątek występuje System.err strumień

Spróbuj posiadające zmienna, która sprawdzi wyjątki i wydrukuje w tej samej konsoli błędów, jeśli wystąpi wyjątek: -

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"); 
     } 
    } 
Powiązane problemy