2013-04-09 11 views
7

私はC++によく慣れています。 (これはユーザーによって拡張することができ、ライブラリクラスです)、私は通常、このようなオブジェクトへのすべての参照と静的なコンテナを持っているクラスのすべてのインスタンスのリストを取得するには、次のJava:クラスのすべてのインスタンスへの参照を保存する方法は?

#include <list> 
class CPPClass; 

class CPPClass { 
    public: 
    CPPClass() { 
     objList.push_back(this); 
    } 
    ~CPPClass() { 
     objList.remove(this); 
    } 

    private: 
    static std::list<CPPClass *> objList; 
}; 

std::list<CPPClass *> CPPClass::objList; 

は、私はどのようにすればいいJavaで同じですか?私はいくつかの懸念があります。複数のクラスローダーがあることを私に言及

  • 誰かが、それは問題
  • のJavaにはデストラクタはありませんが発生する場合がありますので、どのように参照がリストから削除されるのでしょうか?
  • 参照が削除されない場合、これらのオブジェクトはいつガベージコレクションされますか?
+1

[参考文献](http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html)をオブジェクトに保存して、ガベージコレクションを許可します。 – GriffeyDog

答えて

4

簡単なこと:複数のクラスローダーでは、(カスタムクラスローダーを使用して)非標準委譲パターンを使用しない限り、問題は発生しません。このような非標準のクラスローダーをお持ちの場合は、別のバージョンのCPPClassクラス(別のClassLoaderの各バージョン)の異なるバージョンを使用している状況が発生する可能性があります。これにはさまざまな問題があります(CPPClassからCPPClassにキャストするとClassCastExceptionを取得できます)が、静的なコレクションには影響しません。各CPPClassには、独自の個別のコレクションがあります。

次のこと:オブジェクトをコンストラクタからコレクションに追加しないでください。 this参照がコンストラクタからリークすると、メモリモデルの問題が発生する可能性があります。代わりに、オブジェクトを作成し、それを静的コレクションに別々に追加する静的ファクトリメソッドを作成する必要があります。そのコレクションはもちろん、スレッドセーフでなければなりません。

最後に、コアの質問です。各オブジェクトが他のオブジェクトと等しくない場合(つまり、Object.equalsをオーバーライドしていない場合)、オブジェクトをキーとしてWeakHashMapを使用できます。クラスがequalsをオーバーライドする場合は、WeakReferenceのコレクションを作成できます(挿入時やリストの取得時など)。 WeakReferenceは、参照されているオブジェクトがGCされてしまうのを防ぎません。そのGCが発生した後にnullgetから返します。

私はちょっと編集するかもしれませんが、このような "解決策"は、オブジェクトライフサイクルの不確定性を示唆しています。あなたのオブジェクトがCloseableを実装している場合や、それらを使って終了したことを宣言するために同様の方法を使用する方が良いかもしれません。

+0

私は 'equals'メソッドがオーバーライドされていないことに頼ることはできないと思います。なぜなら、ユーザーが望むことを何でもすることができるからです。もし私が最終的にそれを作るのでなければ、私はそれがあまりにも制限的であると思います。私はWeakHashMapの価値を入れますか?だから、WeakArrayListのようなものが残っていると思います(コンテナと呼ばれるものです)。しかし、「Closeable」を実装することは、おなじみの使い慣れたプログラミング方法に戻るように思えますが、理想的なJavaソリューションですか? –

+1

Java 1.7を使用しており、[try-with-resources](http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)を使用したい場合、Closeable(またはAutoCloseable)を実装することは間違いありません慣習的なJava。多くのJDKクラスがそうしています - InputStream、JDBCクラスなどあなた自身のコレクションを使いたいなら、 'List >'から始めましょう。自分のコレクションを最初から実装しないで、JDKコレクションを使用して手動で古いWeakReferencesをパージするだけです。 – yshavit

0

本当にリストを静的にすることができます。正しく初期化することもできます。

List<CPPClass> objlist; 
static { 
    objlist = new List<CPPClass>(); 
} 

または類似のものを実行する必要があります。

参照を削除しないと、ガベージコレクタはオブジェクトがまだ使用されているとみなすため、ガベージコレクションは行われません。

デストラクタのように見えるものがあります:メソッドfinalize。しかし、このメソッドはガベージコレクタによって呼び出されるだけで、それを自分で使用することはできませんので、それはあなたには役に立たないでしょう。

1

オブジェクトへの参照を格納するのではなく、WeakReferenceをオブジェクトに格納します。この方法で、WeakReferenceが残っている唯一の参照である場合、ガベージコレクタはオブジェクトを解放します。

関連する問題