finalize()
ist ein Hinweis an den JVM, dass es vielleicht schön wäre, Ihren Code zu einem unbestimmten Zeitpunkt auszuführen. Dies ist gut, wenn Sie möchten, dass der Code mysteriös nicht ausgeführt wird.
Es ist auch in drei Situationen gut, etwas Bedeutendes in Finalizern zu tun (im Grunde genommen alles außer Logging):
- Sie möchten darauf wetten, dass andere finalisierte Objekte immer noch in einem Zustand sind, den der Rest Ihres Programms als gültig betrachtet.
- Sie möchten viel Überprüfungscode zu allen Methoden aller Ihrer Klassen hinzufügen, die einen Finalizer haben, um sicherzustellen, dass sie sich nach der Finalisierung korrekt verhalten.
- Sie möchten versehentlich finalisierte Objekte wiederbeleben und viel Zeit damit verbringen, herauszufinden, warum sie nicht funktionieren oder warum sie nicht finalisiert werden, wenn sie schließlich freigegeben werden.
Wenn Sie glauben, dass Sie finalize()
benötigen, ist das, was Sie wirklich wollen, manchmal eine Phantomreferenz (die im gegebenen Beispiel einen harten Verweis auf eine Verbindung halten könnte, die von ihrem Referenten verwendet wird, und diese nach dem Einreihen der Phantomreferenz schließen könnte). Dies hat auch die Eigenschaft, dass es möglicherweise mysteriöserweise nie ausgeführt wird, aber zumindest kann es keine Methoden auf finalisierten Objekten aufrufen oder sie wieder beleben. Also ist es genau richtig für Situationen, in denen Sie diese Verbindung nicht unbedingt sauber schließen müssen, aber Sie möchten es gerne, und die Clients Ihrer Klasse können es nicht oder wollen es nicht selbst schließen (was eigentlich fair genug ist - was ist der Sinn eines Garbage Collectors, wenn Sie Schnittstellen entwerfen, die erfordern, dass eine bestimmte Aktion vor der Sammlung durchgeführt wird? Das bringt uns nur zurück in die Zeiten von malloc/free.)
Manchmal benötigen Sie die Ressource, die Sie verwalten zu glauben, robuster zu sein. Warum müssen Sie z.B. diese Verbindung schließen? Es muss letztendlich auf irgendeiner Art von E/A beruhen, die vom System bereitgestellt wird (Socket, Datei, usw.), also warum können Sie sich nicht darauf verlassen, dass das System sie für Sie schließt, wenn die niedrigste Ebene der Ressource gesammelt wird? Wenn der Server am anderen Ende unbedingt verlangt, dass Sie die Verbindung sauber schließen, anstatt einfach den Socket zu schließen, was passiert dann, wenn jemand über das Netzkabel des Geräts stolpert, auf dem Ihr Code läuft, oder das Netzwerk dazwischen ausfällt?
Haftungsausschluss: Ich habe in der Vergangenheit an einer JVM-Implementierung gearbeitet. Ich hasse Finalizer.
0 Stimmen
HI finalize () Methode sehr gut hier erklärt howtodoinjava.com/2012/10/31/…
5 Stimmen
Die meisten Anwendungs- und Bibliothekscodes werden
finalize()
niemals verwenden. Allerdings tut Plattformbibliothekcode, wie z.B.SocketInputStream
, der native Ressourcen im Namen des Aufrufers verwaltet, dies, um das Risiko von Ressourcenlecks zu minimieren (oder verwendet äquivalente Mechanismen wiePhantomReference
, die später hinzugefügt wurden). Daher werden sie im Ökosystem benötigt, obwohl 99,9999% der Entwickler niemals einen schreiben werden.4 Stimmen
Aktualisierung:
finalize
ist ab Java 9 veraltet. Siehe die Frage, Warum ist die finalize() Methode in Java 9 veraltet?.