FinalizeメソッドおよびFinalizeメソッドの使用を慎む

1496 ワード

まずfinalizeメソッドはc++の構造関数とは異なり,jvmは実行を保証しないことを知る.
一、finalizeの使い方を慎む
finalizeメソッドはいつ呼び出されますか:
ごみの回収時にオブジェクトが回収されるときは、まずタグを付け、そのオブジェクトのfinalizeを低優先度のスレッドに配置して実行します.
次のゴミ回収の時にこの対象を回収します.
jvmは、ゴミ回収前にfinalizeメソッドを実行できることを保証していません.finalizeメソッドを実行するスレッドにデッドサイクルが発生しても、他のfinalizeメソッドは実行できません.
二、finalizeメソッドの代替方法
tryを使用...finally...コードブロック、実行する後続の操作をfinallyブロックに入れる
三、finalizeの方法はきっとありませんか
明確にしなければならないいくつかの操作の中で、例えばInputStreamでは、実行が終わったらストリームをオフにしなければならないことを知っています.
ユーザの誤操作を回避するために、InputStreamのfinalizeメソッドでストリームを閉じることができ、リソースの解放に保護ネットワークを追加することができます.必ずしも実行できるとは保証されませんが.
四、終結方法チェーン?
時々このような状況に遭遇する可能性があります
class Superにはcloseメソッドが最後に実行される必要があるので、Superクラスのfinalizeメソッドでは
@Override
protected void finalize() throws Throwable(){
this.close();
}

しかしclass Sub extends Superの場合、サブクラスはSuperのfinalizeメソッドを書き換え、superを呼び出さない.finalize()は、それで終わりです.superのfinalizeメソッドは実行されません.
どうやって解決しますか?
方法1.
@Override
protected void finalize() throws Throwable(){
try{
//finalize subclass state
}finally{
super.finalize();
}
}

もちろん、superクラスを継承する人がこのように書くことを保証することはできません.だから、もっと良い方法があります.
finalizerGuardianを使用するには:
public class Super{
//...

private final Object finalizerGuardian=new Object(){
@Override
protected void finalize() throws Throwable(){
//Super.this.close();
}
}

}

親類が回収される場合、内部の匿名類も必ず回収され、その匿名内部類のfinalizeメソッドはパイプ類がどうやってやっても影響を受けません.巧みではないか.
--Effective Java読後感