[英]Java: how to store references to all instances of a class?
我更習慣C ++。 要獲取類的所有實例的列表(這是一個可以由用戶擴展的庫類),我通常有一個靜態容器,其中包含對這些對象的所有引用:
#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中做同樣的事情? 我有一些顧慮:
簡單的事情:除非使用非標准委托模式(使用自定義類加載器),否則多個類加載器不會導致問題。 如果您確實有這樣的非標准類加載器,那么您可以獲得應用程序的不同部分使用不同版本的CPPClass
類(來自不同ClassLoader的每個版本)的情況。 這有各種各樣的問題(你可以從CPPClass
到CPPClass
獲得一個ClassCastException
轉換!),但它不應該影響你的靜態集合; 每個CPPClass
都有自己獨立的集合。
下一步:不要從構造函數中將對象添加到集合中。 從構造函數中泄漏this
引用可能會導致內存模型問題。 相反,您應該創建一個靜態工廠方法來創建對象,然后將其單獨添加到靜態集合中。 當然,該集合也應該是線程安全的。
最后,核心問題。 如果每個對象不等於任何其他對象(即,如果您沒有覆蓋Object.equals
),則可以使用WeakHashMap ,將對象作為鍵。 如果類確實覆蓋了equals
,則可以創建一個WeakReference集合,您可以在方便的時候剪切(在插入時,在檢索列表時等)。 WeakReference不會阻止它引用的對象被GCed - 它只會在GC發生之后從get
返回null
。
但是,如果我可以稍微進行一些編輯,那么像這樣的“解決方案”通常會暗示一個定義不明確的對象生命周期,這會產生其他可維護性問題。 如果您的對象實現Closeable
或者使用類似的方式來使用它們來聲明它已經完成它可能會更好。
而不是存儲對象的引用 ,將WeakReference存儲到對象 - 這樣,如果WeakReference是唯一保留的引用,則垃圾收集器將釋放對象。
您確實可以將列表設置為靜態,只需確保您也正確初始化它。
List<CPPClass> objlist;
static {
objlist = new List<CPPClass>();
}
或類似的東西應該這樣做。
如果您不刪除引用,它將永遠不會收集垃圾,因為垃圾收集器將假定該對象仍在使用中。
有些東西看起來有點像析構函數:方法finalize
。 但是因為這個方法只是由垃圾收集器調用而你自己不能使用它,所以對你沒用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.