2697 Stimmen

Wird ein finally-Block in Java immer ausgeführt?

Bei diesem Code kann ich sicher sein, dass der finally-Block immer ausgeführt wird, egal was something() ist?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("Ich weiß nicht, ob das ausgegeben wird");
}

672 Stimmen

Wenn dies nicht der Fall ist, sollte das Schlüsselwort wie folgt lauten probably stattdessen.

61 Stimmen

3 Stimmen

Effektives Java sagt etwas anderes informit.com/articles/article.aspx?p=1216151&seqNum=7

19voto

Rajendra Jadi Punkte 189

Nein, nicht immer, eine Ausnahme ist der Fall System.exit(0); bevor der finally Block verhindert, dass finally ausgeführt wird.

      class A {
        public static void main(String args[]) {
            DataInputStream cin = new DataInputStream(System.in);

            try {
                int i = Integer.parseInt(cin.readLine());
            } catch (ArithmeticException e) {
            } catch (Exception e) {
               System.exit(0); // Programm wird beendet, bevor der finally Block ausgeführt wird
            } finally {
                System.out.println("Wird nicht ausgeführt");
                System.out.println("Kein Fehler");
            }
        }
    }

0 Stimmen

Und das ist einer der Gründe, warum Sie niemals System.exit() aufrufen sollten...

19voto

user9189 Punkte 239

Der finally-Block wird immer ausgeführt, es sei denn, das Programm wird abnorm beendet, entweder durch einen Absturz des JVM oder durch einen Aufruf von System.exit(0).

Zusätzlich wird jeder Wert, der innerhalb des finally-Blocks zurückgegeben wird, den vor der Ausführung des finally-Blocks zurückgegebenen Wert überschreiben. Seien Sie also vorsichtig und prüfen Sie alle Ausstiegspunkte beim Verwenden von try finally.

18voto

Außerdem wird ein Return in finally jede Ausnahme verwerfen. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html

12voto

Motti Punkte 104854

Zuletzt wird immer der gesamte Code ausgeführt, nur weil er im Code nach der Rückgabe erscheint, bedeutet das nicht, dass dies so implementiert ist. Die Java-Runtime ist dafür verantwortlich, diesen Code beim Verlassen des try-Blocks auszuführen.

Zum Beispiel, wenn Sie Folgendes haben:

int foo() { 
    try {
        return 42;
    }
    finally {
        System.out.println("fertig");
    }
}

Die Laufzeit generiert etwas Ähnliches wie dies:

int foo() {
    int ret = 42;
    System.out.println("fertig");
    return 42;
}

Wenn eine unbehandelte Ausnahme geworfen wird, wird der finally-Block ausgeführt und die Ausnahme wird weitergeleitet.

12voto

Anonymous Coward Punkte 3071

NICHT IMMER

Die Java Language specification beschreibt, wie try-catch-finally und try-catch Blöcke funktionieren unter 14.20.2
An keiner Stelle wird spezifiziert, dass der finally Block immer ausgeführt wird. Für alle Fälle, in denen die try-catch-finally und try-finally Blöcke vollständig ausgeführt werden, wird jedoch spezifiziert, dass vor Abschluss finally ausgeführt werden muss.

try {
  CODE im try Block
}
finally {
  FIN Code im finally Block
}
Nächster Code wird nach dem try-finally Block ausgeführt (kann in einer anderen Methode sein).

Die JLS garantiert nicht, dass FIN nach CODE ausgeführt wird. Die JLS garantiert, dass wenn CODE und NEXT ausgeführt werden, dann wird FIN immer nach CODE und vor NEXT ausgeführt.

Warum garantiert die JLS nicht, dass der finally Block immer nach dem try Block ausgeführt wird? Weil es unmöglich ist. Es ist unwahrscheinlich, aber möglich, dass die JVM nach Abschluss des try Blocks, aber vor der Ausführung des finally Blocks abgebrochen wird (beendet, abstürzt, heruntergefahren wird). Hiergegen kann die JLS nichts tun.

Daher sind alle Software, die für ihr korrektes Verhalten von der Ausführung der finally Blöcke nach Abschluss ihrer try Blöcke abhängen, fehlerhaft.

return Anweisungen im try Block sind für dieses Problem irrelevant. Wenn die Ausführung den Code nach dem try-catch-finally erreicht, ist garantiert, dass der finally Block bereits ausgeführt wurde, mit oder ohne return Anweisungen innerhalb des try Blocks.

0 Stimmen

Ich bitte um Entschuldigung, dass ich eine so alte Antwort kommentiere, aber ich glaube nicht, dass die Aussage any software which for their proper behaviour depends on finally blocks always being executed after their try blocks complete are bugged. ist völlig richtig. finally Blöcke werden in der Regel zur Bereinigung von Ressourcen verwendet, um Lecks zu verhindern. Wie sollte man es sonst machen? Aus dem gleichen Grund können (oder sollten...) Sie nicht Error s, da es (in der Regel) keine vernünftige Möglichkeit für eine normale Anwendung gibt, mit ihnen umzugehen.

0 Stimmen

@user991710 Wenn es beim Aufräumen im finally-Block zum Beispiel um das Schließen einer offenen Datei geht, dann ist es kein Problem, den finally-Block nicht auszuführen, denn das Betriebssystem schließt ihn bei Programmende. Wenn es beim Aufräumen um das Löschen einer Datei geht, ist das ein Problem, denn das Betriebssystem wird es nicht tun, wenn das Programm vor dem finally-Block abgebrochen wird. Wenn ein anderer Teil des Systems davon abhängt, dass das Java-Programm immer solche Löschungen vornimmt, dann sind das System im Allgemeinen und das Java-Programm im Besonderen fehlerhaft. Man kann sich nicht darauf verlassen, dass finally immer ausgeführt wird. Man kann sich nur auf die Garantie verlassen, dass finally bereits ausgeführt wurde, wenn NEXT ausgeführt wurde.

0 Stimmen

Interessanter Ansatz, obwohl er einige Teile Ihres Entwurfs erzwingt, soweit ich sehen kann. Um Ihr Löschbeispiel zu erweitern: würden Sie eine Art "Reaper"-Aufgabe laufen lassen, die für das Löschen (Aufräumen) von Dateien zuständig ist? Ich gebe zu, dass angesichts Ihrer Erklärung die Verwendung von finally kann (mit genügend Zeit, wahrscheinlich se ) Fehler verursachen, aber ist der zusätzliche Entwicklungs- (und Test-) Aufwand die möglicherweise unbemerkte Verbesserung der Stabilität wert? Allgemeiner ausgedrückt: Hängt der Umfang der Sorgfalt, die einem bestimmten Entwurf gewidmet werden sollte, vom jeweiligen Teilsystem ab? Zeit ist schließlich eine wertvolle Ressource :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X