Ich habe ein kleines theoretisches Problem mit Try-Catch-Konstruktionen.
Ich habe gestern eine praktische Prüfung über Java abgelegt und verstehe folgendes Beispiel nicht:
try {
try {
System.out.print("A");
throw new Exception("1");
} catch (Exception e) {
System.out.print("B");
throw new Exception("2");
} finally {
System.out.print("C");
throw new Exception("3");
}
} catch (Exception e) {
System.out.print(e.getMessage());
}
Die Frage war: "Wie wird die Ausgabe aussehen?"
Ich war mir ziemlich sicher, dass es AB2C3 sein würde, ABER Überraschung Überraschung, es ist nicht wahr.
Die richtige Antwort ist ABC3 (getestet und wirklich so).
Meine Frage ist, wo ist die Ausnahme ("2") geblieben?
print(e.getMessage())
. Sie dachten, die Ausgabe wäreAB2C3
: Haben Sie gedacht, der äußerstecatch
Block würde zweimal ausgeführt?Antworten:
Aus der Java-Sprachspezifikation 14.20.2. ::
Wenn es also einen catch-Block gibt, der eine Ausnahme auslöst:
Es gibt aber auch einen finally-Block, der ebenfalls eine Ausnahme auslöst:
Exception("2")
wird verworfen und nur weitergegebenException("3")
.quelle
return
Aussagen. Wenn Ihr finally-Block eine Rückgabe hat, überschreibt er jede Rückgabe in einemtry
odercatch
-Block. Aufgrund dieser "Funktionen" empfiehlt es sich, dass "finally block" niemals eine Ausnahme auslösen oder eine return-Anweisung haben sollte.Im finally-Block ausgelöste Ausnahmen unterdrücken die zuvor im try- oder catch-Block ausgelöste Ausnahme.
Java 7-Beispiel: http://ideone.com/0YdeZo
Aus Javadocs Beispiel:
Die neue
try-with
Syntax von Java 7 fügt einen weiteren Schritt der Ausnahmeunterdrückung hinzu: Ausnahmen, die im try-Block ausgelöst werden, unterdrücken diejenigen, die zuvor im try-with-Teil ausgelöst wurden.aus demselben Beispiel:
In Code aus Frage verwirft jeder Block eindeutig die alte Ausnahme und protokolliert sie nicht einmal. Dies ist nicht gut, wenn Sie versuchen, einige Fehler zu beheben:
http://en.wikipedia.org/wiki/Error_hiding
quelle
Da
throw new Exception("2");
aus demcatch
Block geworfen wird und nichttry
, wird es nicht wieder gefangen.Siehe 14.20.2. Ausführung von try-finally und try-catch-finally .
Folgendes passiert:
quelle
Ihre Frage ist sehr offensichtlich und die Antwort ist in gleichem Maße einfach. Das Ausnahmeobjekt mit der Nachricht "2" wird vom Ausnahmeobjekt mit der Nachricht "3" überschrieben.
Erläuterung: Wenn eine Ausnahme auftritt, wird das Objekt ausgelöst, um den zu behandelnden Block abzufangen. Wenn jedoch eine Ausnahme im catch-Block selbst auftritt, wird das Objekt zur Ausnahmebehandlung an den OUTER CATCH-Block (falls vorhanden) übertragen. Und das Gleiche geschah hier. Das Ausnahmeobjekt mit der Meldung "2" wird an den OUTER catch-Block übertragen. Aber warte .. Bevor du den inneren Try-Catch-Block verlässt, MUSS er ENDLICH AUSGEFÜHRT werden. Hier trat die Änderung auf, um die wir uns Sorgen machen. Ein neues EXCEPTION-Objekt (mit der Nachricht "3") wird verworfen oder dieser endgültige Block ersetzt das bereits ausgelöste Exception-Objekt (mit der Nachricht "2"). Als Ergebnis erhalten wir, wenn die Nachricht des Exception-Objekts gedruckt wird überschriebener Wert dh "3" und nicht "2".
Beachten Sie: Auf einem CATCH-Block kann nur ein Ausnahmeobjekt behandelt werden.
quelle
Der
finally
Block läuft immer. Entweder Siereturn
aus dem try-Block oder eine Ausnahme wird ausgelöst. Die imfinally
Block ausgelöste Ausnahme überschreibt die im catch-Zweig ausgelöste Ausnahme .Darüber hinaus führt das Auslösen einer Ausnahme nicht zu einer eigenen Ausgabe. Die Zeile
throw new Exception("2");
schreibt nichts aus.quelle
Nach Ihrem Code:
Wie Sie hier sehen können:
# 1
;B - # 2
erfasst.# 3
nach der Anweisung try-catch (oder nur try, wenn keine Ausnahme aufgetreten ist) ausgeführt und drucktC - # 4
und löst eine neue Ausnahme aus.# 5
;Ergebnis ist
ABC3
. Und2
wird auf die gleiche Weise weggelassen wie1
quelle