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

2voto

aliceangel Punkte 264

Der finally-Block wird immer ausgeführt, auch wenn Sie eine return-Anweisung in den try-Block einfügen. Der finally-Block wird vor der return-Anweisung ausgeführt.

2voto

Rubin Luitel Punkte 37

Finally wird immer am Ende aufgerufen

wenn Sie versuchen, es führt einige Code, wenn etwas in Try passiert, dann fangen Sie diese Ausnahme und Sie könnten einige mssg ausdrucken oder einen Fehler werfen, dann schließlich Block ausgeführt wird.

Finally wird normalerweise verwendet, wenn man Aufräumarbeiten durchführt, z. B. wenn man einen Scanner in Java verwendet, sollte man den Scanner wahrscheinlich schließen, da er zu anderen Problemen führt, z. B. dazu, dass man eine Datei nicht öffnen kann

2voto

Mike Punkte 18362

Hier sind einige Bedingungen, unter denen eine endgültige Sperre umgangen werden kann:

  1. Wenn die JVM während der Ausführung des try- oder catch-Codes beendet wird, wird der finally-Block möglicherweise nicht ausgeführt. Mehr über Sonnen-Tutorial
  2. Normales Herunterfahren - dies geschieht entweder, wenn der letzte Nicht-Daemon-Thread beendet wird ODER wenn Runtime.exit() ( ein guter Blog ). Wenn ein Thread beendet wird, führt die JVM eine Bestandsaufnahme der laufenden Threads durch, und wenn die einzigen verbleibenden Threads Daemon-Threads sind, leitet sie ein geordnetes Herunterfahren ein. Wenn die JVM angehalten wird, werden alle verbleibenden Daemon-Threads aufgegeben, Blöcke werden nicht ausgeführt, Stacks werden nicht abgewickelt, die JVM wird einfach beendet. Daemon-Threads sollten sparsam eingesetzt werden, denn nur wenige Verarbeitungsvorgänge können jederzeit sicher und ohne Aufräumarbeiten beendet werden. Insbesondere ist es gefährlich, Daemon-Threads für Aufgaben zu verwenden, die irgendeine Art von E/A durchführen könnten. Daemon-Threads sind am besten für "Haushaltsaufgaben" geeignet, z. B. für einen Hintergrund-Thread, der in regelmäßigen Abständen abgelaufene Einträge aus einem speicherinternen Cache löscht ( Quelle )

Letzter Nicht-Daemon-Thread wird beendet Beispiel:

public class TestDaemon {
    private static Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                while (true) {
                    System.out.println("Is alive");
                    Thread.sleep(10);
                    // throw new RuntimeException();
                }
            } catch (Throwable t) {
                t.printStackTrace();
            } finally {
                System.out.println("This will never be executed.");
            }
        }
    };

    public static void main(String[] args) throws InterruptedException {
        Thread daemon = new Thread(runnable);
        daemon.setDaemon(true);
        daemon.start();
        Thread.sleep(100);
        // daemon.stop();
        System.out.println("Last non-daemon thread exits.");
    }
}

Ausgabe:

Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive

1voto

Youngrok Ko Punkte 175

Try-with-resoruce Beispiel

static class IamAutoCloseable implements AutoCloseable {
    private final String name;
    IamAutoCloseable(String name) {
        this.name = name;
    }
    public void close() {
        System.out.println(name);
    }
}

@Test
public void withResourceFinally() {
    try (IamAutoCloseable closeable1 = new IamAutoCloseable("closeable1");
         IamAutoCloseable closeable2 = new IamAutoCloseable("closeable2")) {
        System.out.println("try");
    } finally {
        System.out.println("finally");
    }
}

Testausgabe:

try
closeable2
closeable1
finally

0voto

kevinarpe Punkte 18905

Ich bin schrecklich spät dran, um hier zu antworten, aber ich bin überrascht, dass niemand die Java-Debugger-Option erwähnt hat, einen Stack-Frame zu löschen. Ich benutze diese Funktion in IntelliJ sehr häufig. (Ich bin sicher Eclipse und NetBeans unterstützen die gleiche Funktion).

Wenn ich einen Stack-Frame aus einem Try- oder Catch-Block fallen lasse, auf den ein Finally-Block folgt, wird die IDE mich dazu auffordern: "Soll ich den finally-Block ausführen?" Offensichtlich ist dies eine künstliche Laufzeitumgebung - ein Debugger!

Um Ihre Frage zu beantworten, würde ich sagen, Sie können nur garantieren, dass es läuft, wenn ignorieren, wenn ein Debugger angeschlossen ist, und (wie andere gesagt) Methode something() ruft nicht (a) die Java-Methode System.exit(int) oder (b) C-Funktion exit(int) / abort() über JNI oder (c) etwas Verrücktes tun wie den Aufruf kill -9 $PID auf sich selbst(!).

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