1. ホーム
  2. java

[解決済み] なぜfinalize()を実装する必要があるのでしょうか?

2022-03-24 17:27:34

質問

のルーキーJavaの質問をたくさん読んできました。 finalize() がリソースをクリーンアップするための信頼性の低い方法であることを誰も明確にしないことに困惑しているようです。 コネクションを閉じることを保証する唯一の方法は try (catch) finally を実装することなので、これは本当に恐ろしいことです。

私はCSを学んだわけではありませんが、専門的にJavaでプログラミングを始めてから10年近く経ちますが、これまで誰も finalize() を、本番システムで使用したことは一度もありません。 それでも、使い道がないわけではありませんし、私が一緒に仕事をした人たちが正しくやっていたわけでもありません。

そこで質問なのですが、どのようなユースケースを想定して finalize() 他のプロセスや言語内の構文でより確実に処理することができないものですか?

単にJavaの教科書やfinalizeの使用目的を繰り返すだけでは不十分ですし、この質問の意図とは異なりますので、具体的なシナリオやあなたの経験を教えてください。

どのように解決するのですか?

外部リソース(ソケット、ファイルなど)を保持するオブジェクトのバックストラップとして使用することができます。 を実装します。 close() メソッドを呼び出し、それが必要であることを文書化します。

実装 finalize() を実行するために close() の処理が行われていないことを検出した場合、その処理を行います。おそらく stderr バグのある呼び出し元の後始末をしていることを指摘するためです。

これは、例外的な/バギーな状況において、さらなる安全性を提供するものです。 すべての呼び出し元が正しい try {} finally {} のようなものが毎回あります。 残念なことですが、ほとんどの環境ではそうです。

めったに必要でないことは同意します。 そして、コメント欄で指摘されているように、GCのオーバーヘッドを伴う。 長時間稼働するアプリで、ベルトとサスペンダーのような安全性が必要な場合のみ使用してください。

Java9の時点ではそうなんですね。 Object.finalize() は非推奨です! それらは私たちに java.lang.ref.Cleaner java.lang.ref.PhantomReference を代替とする。