Dies mag wie eine Programmierfrage erscheinen, und ich hatte gedacht, ich wüsste die Antwort, aber jetzt muss ich sie noch einmal überprüfen. Wird in diesem Code unten die im ersten catch-Block ausgelöste Ausnahme vom allgemeinen Ausnahme-catch-Block unten abgefangen?
try {
// Do something
} catch(IOException e) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}
Ich dachte immer, die Antwort wäre nein, aber jetzt habe ich ein merkwürdiges Verhalten, das dadurch verursacht werden könnte. Die Antwort ist wahrscheinlich für die meisten Sprachen dieselbe, aber ich arbeite in Java.
Antworten:
Nein, da das neue
throw
nichttry
direkt im Block ist.quelle
RuntimeException
aus demcatch
Block geworfen wird, tritt kein Kompilierungsfehler auf.catch
aufgeführt wird . Ich verstehe, dass Java dies nicht zulässt und es beim Kompilieren abgefangen wird.catch
Nein, es ist sehr einfach zu überprüfen.
Sollte drucken:
Technisch gesehen könnte dies ein Compiler-Fehler, ein implementierungsabhängiges, nicht angegebenes Verhalten oder etwas anderes sein. Das JLS ist jedoch ziemlich gut festgenagelt und die Compiler sind gut genug für diese Art von einfachen Dingen (Generics Corner Case kann eine andere Sache sein).
Beachten Sie auch, dass beim Kompilieren der beiden Fangblöcke keine Kompilierung erfolgt. Der zweite Fang wäre völlig unerreichbar.
Beachten Sie, dass der finally-Block immer ausgeführt wird, auch wenn ein catch-Block ausgeführt wird (abgesehen von dummen Fällen wie Endlosschleifen, Anhängen über die Werkzeugschnittstelle und Beenden des Threads, Umschreiben des Bytecodes usw.).
quelle
finally
ist natürlich anzurufenSystem.exit
. :-Pfor(;;);
ist kürzer, in der Sprache enthalten, führt nicht viel zu Nebenwirkungen und ist für mich offensichtlicher.System.exit
ist CPU-freundlicher! : -O Aber ja, okay, das ist eindeutig ein subjektives Kriterium. Außerdem wusste ich nicht, dass Sie ein Code-Golfer sind. ;-)In der Java-Sprachspezifikation heißt es in Abschnitt 14.19.1:
Referenz: http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#24134
Mit anderen Worten, der erste einschließende Fang, der die Ausnahme behandeln kann, funktioniert, und wenn eine Ausnahme aus diesem Fang herausgeworfen wird, liegt dies nicht im Umfang eines anderen Fangs für den ursprünglichen Versuch, sodass sie nicht versuchen, damit umzugehen.
Eine verwandte und verwirrende Sache zu wissen ist, dass in einer try- [catch] -finally-Struktur ein finally-Block eine Ausnahme auslösen kann und in diesem Fall jede vom try- oder catch-Block ausgelöste Ausnahme verloren geht. Das kann verwirrend sein, wenn Sie es zum ersten Mal sehen.
quelle
try
-with-resources vermeiden können. Wenn danntry
UNDfinally
beide werfen,finally
wird unterdrückt, aber auch zur Ausnahme von HINZUGEFÜGTtry
. Wenn Sie ebenfallscatch
werfen, haben Sie kein Glück, es sei denn, Sie erledigen das selbst über 'addSuppressed' und fügen dietry
Ausnahme hinzu - dann haben Sie alle drei.Wenn Sie eine Ausnahme aus dem catch-Block auslösen möchten, müssen Sie Ihre Methode / Klasse / etc. dass es diese Ausnahme werfen muss. Wie so:
Und jetzt wird dein Compiler dich nicht anschreien :)
quelle
Nein - Wie Chris Jester-Young sagte, wird es bis zum nächsten Versuch in der Hierarchie geworfen.
quelle
Wie oben erwähnt ...
Ich möchte hinzufügen, dass Sie, wenn Sie Probleme haben, die Vorgänge zu sehen, das Trace im Debugger nicht reproduzieren können, eine Ablaufverfolgung hinzufügen können, bevor Sie die neue Ausnahme erneut auslösen (mit dem guten alten System) .out.println schlimmer noch, mit einem guten Protokollsystem wie log4j sonst).
quelle
Es wird nicht vom zweiten Fangblock erfasst. Jede Ausnahme wird nur in einem Try-Block abgefangen. Sie können jedoch Versuche verschachteln (nicht, dass dies im Allgemeinen eine gute Idee ist):
quelle
Nein, da sich alle Catches auf denselben Try-Block beziehen, wird das Werfen aus einem Catch-Block heraus von einem umschließenden Try-Block abgefangen (wahrscheinlich in der Methode, die diesen aufgerufen hat).
quelle
Alter Beitrag, aber "e" -Variable muss eindeutig sein:
quelle