

「Javaのfinalizeによるクリーンアップ処理の実装は行うべきではない」と教わったのですが、なぜそうなのでしょう？  
また、finalizeを使わずに同じようなことをすることはできるのでしょうか？


CC BY-SA 3.0
2016-02-01T10:20:08.010
21575
2016-02-02T08:08:34.663
450
question
java
どうしてfinalizeを使うべきではないのですか？


コメントで教えていただいたところにとても良く書いてあったので、自分でまとめます。

finalizeはいつ呼ばれるかわからないし、呼ばれないかもしれない。JVMの実装にも依存するのでコードの可搬性が失われる。また、finalizeはファイナライズスレッドで実行されるが、ここで例外が発生してもエラーにはならず、オブジェクトが中途半端な状態でメモリに残る可能性がある。  
だから、そんな不安定な処理に依存する処理は書くべきではない。


CC BY-SA 3.0
2016-02-01T16:35:49.797
21588
2016-02-01T16:35:49.797
450
21575
answer


さまざまなブログや記事がありますが、一番詳細に書かれているのはJPCertのこちらのページでしょうか。

<https://www.jpcert.or.jp/java-rules/met12-j.html>

特に気になるところとしては、

  * ファイナライザの実行は、オブジェクトが到達不能になった後、どれだけ延期されるか分からない。
  * JVMは、到達不能なオブジェクトのファイナライザを実行せずに終了するかもしれない。つまり、ファイナライザメソッドにおいて(オブジェクトの)重要な永続的状態を更新しようとしても、警告なしに失敗するかもしれない。→つまりファイルのロックや接続プールが残ったままの可能性がある。

…と、あとは様々な欠点が書かれており、独自に実装すべきではない、とも強く書かれています。

finalyzeの代替手段とは言えませんが、取得したリソースの開放は適切に行う（残しっぱなしにしない、例外ハンドリングを忘れない）ことでしょうか。


CC BY-SA 3.0
2016-02-02T08:08:34.663
21617
2016-02-02T08:08:34.663
5778
21575
answer