0

Closable を実装するクラス MyClass を作成したとしましょう。したがって、close() メソッドでは、いくつかの非常に重要なリソースを解放します。非常に重要なリソースであるため、ある種の安全ネットワークを作成しました (Effective Java で推奨されているように)。ここにあります:

protected void finalize(){
if (/*user didn't call close() method by himself*/){
    close();
}
}

最初はとても嬉しかったのですが、後でファイナライザーはそれほどクールではなく、PhantomReference のようなクールなツールがあることを知りました。そこで、finalize() メソッドの代わりに PhantomReference を使用するようにコードを変更することにしました。PhantomRefernce を拡張した CustomPantom を作成しました。ここにあります:

public class CustomPhantom extends PhantomReference {

//Object cobj;

public CustomPhantom(Object referent, ReferenceQueue q) {
    super(referent, q);
    //this.cobj = referent;   can't save the refference to my object in a class field,
                        // because it will become strongly rechable 
                        //and PhantomReference won't be put to the reference queue  
}

public void cleanup(){
    //here I want to call close method from my object, 
            //but I don't have a reference to my object
}
}

したがって、オブジェクトへの参照を取得できる唯一の方法は、リフレクションを使用して、Reference クラスにある参照対象フィールドから if を取得することです。これは、クリーンアップ メソッドから MyClass.close() を呼び出す唯一の方法ですか?

PSここにすべてのコードを投稿したわけではありませんが、テストしたところすべて正常に動作します。ReferenceQueue は PhantomReferences で満たされているので、それらを 1 つずつ取得してクリーンアップ メソッドを呼び出すことができます。しかし、リフレクションを使用せずに上記の問題を解決する方法がわかりません。

4

2 に答える 2

1

ファントム参照を使用してこのようなことを行うことはできません。リフレクションでさえ役に立ちません。ReferenceQueueGC が既に発生した後にのみ参照を取得するため、呼び出すオブジェクトはもうありませんclose()

できることの 1 つは、実際には良いアイデアですが、 を使用して、直接呼び出す必要があったのに呼び出しを行わなかったPhantomReferenceというエラーをスローすることです。close()たとえば、参照先オブジェクトに への参照を持たせ、メソッドCustomPhantomを呼び出すことができます。CustomPhantom.setCleanedUp(true)次に、 でクリーンアップされていないCustomPhantom場合ReferenceQueueは、警告を表示できます。

于 2014-04-07T20:23:15.553 に答える