簡體   English   中英

Java:如何存儲對類的所有實例的引用?

[英]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中做同樣的事情? 我有一些顧慮:

  • 有人向我提到可能有多個類加載器,這可能會導致問題
  • java中沒有析構函數,那么如何從列表中刪除引用?
  • 如果沒有刪除引用,這些對象什么時候被垃圾收集?

簡單的事情:除非使用非標准委托模式(使用自定義類加載器),否則多個類加載器不會導致問題。 如果您確實有這樣的非標准類加載器,那么您可以獲得應用程序的不同部分使用不同版本的CPPClass類(來自不同ClassLoader的每個版本)的情況。 這有各種各樣的問題(你可以從CPPClassCPPClass獲得一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM