Java Try Catch Endlich blockiert ohne Catch

125

Ich überprüfe einen neuen Code. Das Programm hat nur einen Versuch und einen Endblock. Wie funktioniert der try-Block, wenn der catch-Block ausgeschlossen ist, wenn er auf eine Ausnahme oder etwas Auslösbares stößt? Geht es nur direkt zum Endblock?

NullPointer0x00
quelle
2
Mögliches Duplikat des Unterschieds zwischen Try-finally und Try-Catch
Pablo Fernandez
25
@mP Jeder sollte Codeüberprüfungen durchführen und Fragen an ihn stellen, um zu lernen und sich zu verbessern.
Carl Pritchett

Antworten:

130

Wenn einer der Codes im try-Block eine aktivierte Ausnahme auslösen kann, muss er in der throw-Klausel der Methodensignatur erscheinen. Wenn eine nicht aktivierte Ausnahme ausgelöst wird, wird sie aus der Methode entfernt.

Der finally-Block wird immer ausgeführt, unabhängig davon, ob eine Ausnahme ausgelöst wird oder nicht.

Duffymo
quelle
11
Der erste Absatz ist nicht unbedingt wahr. Versuchsblöcke können verschachtelt werden. Jede nicht erfasste Ausnahme, ob deaktiviert oder nicht, wird aus der Methode heraussprudeln.
Andy Thomas
4
Try-Blöcke können verschachtelt werden, aber ich würde es nicht empfehlen. Ich schreibe keinen Code so.
Duffymo
2
@duffymo: Was bedeutet "aus der Methode herausgesprudelt"?
TodayILearned
5
@Anand nur eine etwas nicht-technische Sprache für "eine Ausnahme auslösen".
Duffymo
2
Nicht ignoriert; Übergeben Sie die Methodenkette.
Duffymo
93

Ein kleiner Hinweis zu try/ finally: Das wird immer ausgeführt, es sei denn

  • System.exit() wird genannt.
  • Die JVM stürzt ab.
  • Der try{}Block endet nie (zB Endlosschleife).
Peter Lawrey
quelle
4
Was ist mit try{..} catch{ throw ..} finally{..}? Ich denke, endlich wird nicht hingerichtet
sbeliakov
10
In diesem Fall wird schließlich noch aufgerufen. Nur die ursprüngliche Ausnahme geht verloren.
Peter Lawrey
Schließlich wird es auch nicht ausgeführt, wenn Sie zuvor System.exit () aufrufen.
mmirror
2
@jyw Das habe ich mit dem ersten Punkt in der obigen Liste gemeint.
Peter Lawrey
Ich muss sagen, das deckt alle Grundlagen ab!
Oscar Bravo
39

Die Java-Sprachspezifikation (1) beschreibt, wie try-catch-finallyausgeführt wird. Kein Fang zu haben ist gleichbedeutend damit, keinen Fang zu haben, der in der Lage ist, den gegebenen Wurf zu fangen.

  • Wenn die Ausführung des try-Blocks aufgrund eines Wurfs eines Werts V abrupt abgeschlossen wird, gibt es eine Auswahl:
    • Wenn der Laufzeittyp von V dem Parameter einer catch-Klausel der try-Anweisung zugewiesen werden kann, dann
      ……
    • Wenn der Laufzeittyp von V dem Parameter einer catch-Klausel der try-Anweisung nicht zuweisbar ist, wird der finally-Block ausgeführt . Dann gibt es eine Wahl:
      • Wenn der finally-Block normal ausgeführt wird, wird die try-Anweisung aufgrund eines Wurfs des Werts V abrupt abgeschlossen.
      • Wenn der finally-Block aus Grund S abrupt abgeschlossen wird, wird die try-Anweisung aus Grund S abrupt abgeschlossen (und der Wurf des Werts V wird verworfen und vergessen).

(1) Ausführung von try-catch-finally

user85421
quelle
16

Das innere wird schließlich ausgeführt, bevor die Ausnahme auf den äußeren Block geworfen wird.

public class TryCatchFinally {

  public static void main(String[] args) throws Exception {

    try{
        System.out.println('A');
        try{
            System.out.println('B');
            throw new Exception("threw exception in B");
        }
        finally
        {
            System.out.println('X');
        }
        //any code here in the first try block 
        //is unreachable if an exception occurs in the second try block
    }
    catch(Exception e)
    {
        System.out.println('Y');
    }
    finally
    {
        System.out.println('Z');
    }
  }
}

Ergebnisse in

A
B
X
Y
Z
Skipchaser
quelle
6

Der finally-Block wird immer ausgeführt, nachdem der try-Block beendet wurde, unabhängig davon, ob der try-Vorgang aufgrund einer Ausnahme normal oder abnormal beendet wurde.

Wenn eine Ausnahme von einem der Codes im try-Block ausgelöst wird, löst die aktuelle Methode dieselbe Ausnahme einfach erneut aus (oder löst sie weiterhin aus) (nachdem der finally-Block ausgeführt wurde).

Wenn der finally-Block eine Ausnahme / error / throwable auslöst und bereits ein ausstehendes throwable vorhanden ist, wird es hässlich. Ehrlich gesagt vergesse ich genau, was passiert (so viel zu meiner Zertifizierung vor Jahren). Ich denke beide Throwables werden miteinander verbunden, aber es gibt ein spezielles Voodoo, das Sie tun müssen (dh einen Methodenaufruf, den ich nachschlagen müsste), um das ursprüngliche Problem zu lösen, bevor sich das "endgültige" Barfed, ähm, übergeben hat.

Übrigens ist try / finally eine ziemlich häufige Aufgabe für das Ressourcenmanagement, da Java keine Destruktoren hat.

Z.B -

r = new LeakyThing();
try { useResource( r); }
finally { r.release(); }  // close, destroy, etc

"Endlich", noch ein Tipp: Wenn Sie sich die Mühe machen, einen Fang einzufügen, fangen Sie entweder bestimmte (erwartete) Wurf-Unterklassen oder fangen Sie einfach "Wurfbar", nicht "Ausnahme", für eine allgemeine Fehlerfalle. Zu viele Probleme, wie z. B. Reflexionsfehler, werfen eher "Fehler" als "Ausnahmen" aus, und diese rutschen direkt an jedem "Fang alle" vorbei, der wie folgt codiert ist:

catch ( Exception e) ...  // doesn't really catch *all*, eh?

Tun Sie dies stattdessen:

catch ( Throwable t) ...
Roboprog
quelle
Siehe die Antwort von Carlos Heuberger unten für den hässlichen Teil.
Mplwork
3

Java-Versionen vor Version 7 ermöglichen diese drei Kombinationen von try-catch-finally ...

try - catch
try - catch - finally
try - finally

finallyDer Block wird immer ausgeführt, unabhängig davon, was im tryoder / und catchBlock vor sich geht. Wenn also kein catchBlock vorhanden ist , wird die Ausnahme hier nicht behandelt.

Sie benötigen jedoch weiterhin irgendwo in Ihrem Code einen Ausnahmebehandler - es sei denn, Sie möchten, dass Ihre Anwendung natürlich vollständig abstürzt. Es hängt von der Architektur Ihrer Anwendung ab, wo genau sich dieser Handler befindet.

  • Auf den Java-Try-Block muss entweder catch oder finally block folgen.
  • Für jeden Try-Block kann es null oder mehr Catch-Blöcke geben, aber nur einen Endblock.
  • Der finally-Block wird nicht ausgeführt, wenn das Programm beendet wird (entweder durch Aufrufen von System.exit () oder durch Verursachen eines schwerwiegenden Fehlers, der zum Abbruch des Prozesses führt).
Roottraveller
quelle
1
"vor Version 7 zulassen" implizieren Sie, dass Java 7 und Java 8 diese drei Kombinationen nicht zulassen? Ich bezweifle, dass Sie das meinen, aber das impliziert Ihre Antwort.
Loduwijk
Wird der finally-Block ausgeführt, wenn der try-Block eine return-Anweisung enthält?
Rahul Yadav
@ Rahul Ja, endlich wird angerufen. Ref: stackoverflow.com/questions/65035/…
Roottraveller
1
@Aaron - neue Syntax für try-with-resource, die automatisch .close () für alles aufruft, was in parens direkt nach dem Schlüsselwort try erstellt wurde.
Roboprog
2

Wie funktioniert der try-Block, wenn er auf eine Ausnahme oder etwas Auslösbares stößt?

Die Ausnahme wird aus dem Block geworfen, genau wie in jedem anderen Fall, in dem sie nicht abgefangen wird.

Der finally-Block wird unabhängig davon ausgeführt, wie der try-Block verlassen wird - unabhängig davon, ob überhaupt Catches vorhanden sind, unabhängig davon, ob ein passender Catch vorhanden ist.

Die Fangblöcke und die schließlich sind orthogonale Teile des Versuchsblocks. Sie können eines oder beide haben. Mit Java 7 können Sie beides nicht haben!

Andy Thomas
quelle
1

Versuchen Sie es nicht mit diesem Programm? Es wird endgültig blockiert und der endgültige Block ausgeführt, aber die Ausnahme wird nicht behandelt. Diese Ausnahme kann jedoch im finally-Block außer Kraft gesetzt werden!

Abimaran Kugathasan
quelle
1

Der finally-Block wird ausgeführt, nachdem der try-Block abgeschlossen ist. Wenn beim Verlassen etwas in den try-Block geworfen wird, wird der finally-Block ausgeführt.

mP.
quelle
0

Innerhalb des tryBlocks schreiben wir Codes, die eine Ausnahme auslösen können. In dem catchBlock behandeln wir die Ausnahme. Der finallyBlock wird immer ausgeführt, unabhängig davon, ob eine Ausnahme auftritt oder nicht.

Wenn wir nun try-finally-Block anstelle von try-catch-finally-Block haben, wird die Ausnahme nicht behandelt, und nach dem try-Block anstelle der Steuerung, die den Block abfängt, wird sie endgültig blockiert. Wir können den try-finally-Block verwenden, wenn wir mit der Ausnahme nichts tun möchten.

Animesh Jaiswal
quelle
0

Unabhängig davon, welche Ausnahme im tryBlock ausgelöst wird oder nicht, wird der Block finallyausgeführt. Ausnahme würde nicht gefangen werden.

Kreker
quelle