368 Stimmen

Wann wird die Methode finalize() in Java aufgerufen?

Ich muss wissen, wann die [finalize()](https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#finalize()) Methode wird in der JVM . Ich habe eine Testklasse erstellt, die in eine Datei schreibt, wenn die finalize() Methode aufgerufen wird, indem sie überschrieben wird. Sie wird nicht ausgeführt. Kann mir jemand den Grund dafür nennen, warum sie nicht ausgeführt wird?

399voto

Joachim Sauer Punkte 290477

En finalize Methode wird aufgerufen, wenn ein Objekt im Begriff ist, Garbage Collect zu werden. Das kann zu jedem Zeitpunkt sein, nachdem es für die Garbage Collection in Frage kommt.

Beachten Sie, dass es durchaus möglich ist, dass ein Objekt nie garbage collected wird (und somit finalize nie aufgerufen wird). Dies kann passieren, wenn das Objekt nie für die Garbage Collection in Frage kommt (weil es während der gesamten Lebensdauer der JVM erreichbar ist) oder wenn zwischen dem Zeitpunkt, an dem das Objekt für die Garbage Collection in Frage kommt, und dem Zeitpunkt, an dem die JVM aufhört zu laufen, keine Garbage Collection durchgeführt wird (dies geschieht häufig bei einfachen Testprogrammen).

Es gibt verschiedene Möglichkeiten, der JVM mitzuteilen, dass sie Folgendes ausführen soll finalize bei Objekten, die noch nicht aufgerufen wurden, aber es ist auch keine gute Idee, sie zu benutzen (die Garantien dieser Methode sind auch nicht sehr stark).

Wenn Sie sich auf finalize für den korrekten Betrieb Ihrer Anwendung, dann machen Sie etwas falsch. finalize sollte nur für die Bereinigung von (normalerweise Nicht-Java-) Ressourcen verwendet werden. Und das ist genau weil die JVM nicht garantiert, dass finalize jemals für ein Objekt aufgerufen wird.

294voto

Im Allgemeinen ist es am besten, sich nicht auf finalize() Aufräumarbeiten usw. zu erledigen.

Nach Angaben der Javadoc (was es wert wäre, gelesen zu werden), ist es das:

Wird vom Garbage Collector für ein Objekt aufgerufen, wenn die Garbage Collection feststellt, dass es keine Referenzen mehr auf das Objekt gibt.

Wie Joachim schon sagte, kann dies im Leben eines Programms nie passieren, wenn das Objekt immer zugänglich ist.

Außerdem ist nicht garantiert, dass der Garbage Collector zu einer bestimmten Zeit läuft. Was ich damit sagen will, ist im Allgemeinen finalize() ist wahrscheinlich nicht die beste Methode, es sei denn, es gibt etwas Bestimmtes, wofür man sie braucht.

78voto

XpiritO Punkte 2794
protected void finalize() throws Throwable {}
  • jede Klasse erbt die finalize() m java.lang.Object

  • die Methode wird vom Garbage Collector aufgerufen, wenn er feststellt keine weiteren Referenzen auf das Objekt existieren

  • die Methode Object finalize perfo jede Klasse

  • Normalerweise sollte es überschrieben werden, um Nicht-Java-Ressourcen zu bereinigen einer Datei

  • bei Überschreitung finalize() es ist eine gute Programmierpraxis try-catch-finally-Anweisung zu verwenden und immer aufzurufen super.finalize() . Diese ist eine Sicherheitsmaßnahme, um sicherzustellen, dass Sie nicht versehentlich das Schließen einer Ressource zu schließen, die von den Objekten verwendet wird, die Klasse

    protected void finalize() throws Throwable {
         try {
             close();        // close open files
         } finally {
             super.finalize();
         }
     }
  • jede Ausnahme, die durch finalize() bei der Müllabfuhr Abschluss, wird aber ansonsten ignoriert

  • finalize() wird nie mehr als einmal für ein Objekt ausgeführt

zitiert nach: http://www.janeg.ca/scjp/gc/finalize.html

Sie können auch diesen Artikel lesen:

27voto

rsp Punkte 22749

Die Java finalize() Methode ist kein Destruktor und sollte nicht verwendet werden, um Logik zu behandeln, von der Ihre Anwendung abhängt. Die Java-Spezifikation besagt, dass es keine Garantie dafür gibt, dass die finalize Methode wird während der Laufzeit der Anwendung überhaupt nicht aufgerufen.

Was Sie wahrscheinlich wollen, ist eine Kombination aus finally und eine Bereinigungsmethode, wie in:

MyClass myObj;

try {
    myObj = new MyClass();

    // ...
} finally {
    if (null != myObj) {
        myObj.cleanup();
    }
}

Damit wird die Situation korrekt behandelt, wenn die MyClass() Konstruktor eine Ausnahme auslöst.

19voto

Hao Deng Punkte 625

Lesen Sie Effective Java, 2. Auflage, Seite 27. Punkt 7: Finalisten vermeiden

Finalisten sind unberechenbar, oft gefährlich und im Allgemeinen unnötig. nie etwas Zeitkritisches in einem Finalizer tun. nie von einem Finalizer abhängen, um kritische persistente Zustände zu aktualisieren.

Um eine Ressource zu beenden, verwenden Sie stattdessen try-finally:

// try-finally block guarantees execution of termination method
Foo foo = new Foo(...);
try {
    // Do what must be done with foo
    ...
} finally {
    foo.terminate(); // Explicit termination method
}

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