Meine Frage bezieht sich auf das syntaktische Verhalten des try catch Blocks
Leer Versuch Block mit einem Haken als dies
%Vor%oder
%Vor%kompiliert gut, aber der Compiler beschwert sich mit
%Vor%Warum erlaubt der Compiler das Abfangen von Objekten vom Typ "Exception" oder "RuntimeException", während er sich über nicht erreichbaren Code mit geprüften Ausnahmen beschwert? Ist es, weil der JVM-Code diese Typen werfen kann? Wie könnte die JVM ArrayIndexOutOfBoundsException möglicherweise in einen leeren try-Block werfen?
Der leere Block ist ein Spezialfall, der von der JLS nicht speziell behandelt wird. Was die JLS erfordert ist, dass, wenn Sie eine geprüfte Ausnahme abfangen, der Code im Block try
in der Lage sein muss, diese Ausnahme zu werfen (dh, sie hat sie direkt ausgelöst oder eine Methode aufgerufen, die wurde erklärt, um es möglicherweise zu werfen).
Mit anderen Worten, es gibt eine Sicherheitsüberprüfung speziell für geprüfte Ausnahmen, aber nicht für alle Ausnahmen, bei denen geprüfte Ausnahmen besondere Beachtung finden.
Dies wird in JLS 14.21 beschrieben. und speziell:
Es ist ein Fehler bei der Kompilierung, wenn eine Anweisung nicht ausgeführt werden kann, weil sie nicht erreichbar ist.
...
Ein Catch-Block
C
ist erreichbar, wenn beide der folgenden Bedingungen zutreffen:
Entweder der Typ von
C
's Parameter ist ein uncheckter Ausnahme-Typ oderException
oder eine Oberklasse vonException
, oder eine Ausdrucks- oder throw-Anweisung im try-Block ist erreichbar und kann eine geprüfte Ausnahme auslösen, deren Typ dem Typ des ParametersC
zuweisbar ist. (Ein Ausdruck ist erreichbar, wenn die innerste Anweisung, die ihn enthält, erreichbar ist.)Siehe § 15.6 für normale und abrupte Vervollständigung von Ausdrücken.
Es gibt keinen früheren catch-Block
A
in der try-Anweisung, so dass der Typ des ParametersC
der gleiche ist wie oder eine Unterklasse des TypsA
's Parameter.
Hervorhebung hinzugefügt: Es zeigt, dass der catch-Block erreichbar ist, wenn Sie einen ungeprüften Ausnahme-Typ abfangen.
Ich persönlich finde den Wortlaut etwas verwirrend. Leicht umformuliert, der erste Aufzählungspunkt sagt nur, dass die Fangklausel eines von fangen muss:
Exception
Throwable
(das ist die einzige Oberklasse von Exception
anders als Object
, die Sie nicht fangen können) try
-Block Die zweite Aufzählung schützt davor, dass ein catch
-Baustein wegen eines vorherigen catch
in diesem try
nicht erreichbar ist. Zum Beispiel: