プログラマメモ2 - programmer no memo2

finalizeの実装(オーバライド) 2006/06/26
2006/11/26

個人的には、Object#finalize()は実装せずに、後始末が必要な処理は早い段階で明示的に後始末メソッドを作って行うようにしたほうがよいと思う。



この根拠は、

(1)

finalizeの呼び出しは、JVMに依存している。

(2)

finalizeの処理が時間かかる場合にアプリケーション全体の動作にたいする影響にたいしての危惧

(3)

super.finalize()の呼び出しにたいする注意が必要になる



finalizeの呼び出しに過渡なきたいをしたくないというのが本音。

プログラマができる後始末はちゃちゃとすませたほうが吉なのではないだろうか。

たしか、Syste.gc()の呼び出しはすすめられていなかったと思う。

※もとネタを探し中



といいつつも

ではどういったときにプログラマはfinalizeを実装したほうがよいのだろうか。

JNI(Java Native Interface)を利用したりして実メモリ操作に近い処理をしているような場合だろうか。



Javaのソースコードを簡単に調べてみた。

なんとなくパターンがある感じ。



(A)

java.awt.Font

で実装しているコードがあった。

これはあきらかにネイティブなものにたいする後始末パターン。

下記のような感じ。



/** ネイティブコール */

private native void pDispose();

/** overrideされている */

protected void finalize() throws Throwable {

if (this.peer != null) {

pDispose();

}

super.finalize();

}





(B)

java.awt.Window

これは、登録していたものから自分を削除するパターン(かな?)

で下記のような感じ。



protected void finalize() throws Throwable {

if (parent != null) {

((Window)parent).removeOwnedWindow(weakThis);

}

super.finalize();

}





(C)

javax.imageio.stream.ImageInputStreamImpl

これは、おそらくクローズしわすれ防止パターン。

下記のような感じのコード。



protected void finalize() throws Throwable {

if (!isClosed) {

try {

close();

} catch (IOException e) {}

}

super.finalize();

}





気がついたことがあるsuper.finalize()の呼び方が下のほうにある。



いまいちよくわかってないので、引き続き考えていきたい。

: