Java: how to store references to all instances of a class?
garbage-collection, java, static
Solution
Easy things first: multiple classloaders won't cause you a problem unless you use a non-standard delegation pattern (with a custom classloader). If you do have such a non-standard classloader, you can get a situation wheredifferent parts of the app are using different versions of the `CPPClass` class (each version from a different ClassLoader). This has various issues (you can get a `ClassCastException` casting from `CPPClass` to `CPPClass`!), but it shouldn't affect your static collection; each `CPPClass` will just have its own, separate collection.
Next thing: don't add the objects to the collection from the constructor. Leaking the `this` reference from a constructor can lead to memory model problems. Instead, you should create a static factory method that creates the object and then separately adds it to the static collection. That collection should also be thread-safe, of course.
Finally, the core question. If each object is not equal to any other object (that is, if you haven't overridden `Object.equals`), you could use a WeakHashMap, with the objects as keys. If the class does override `equals`, you can create a collection of WeakReferences, which you can prune at convenient times (on insert, on retrieving the list, etc.). A WeakReference will not prevent the object it refers to from being GCed -- it'll just return `null` from `get` after that GC has happened.
But if I may editorialize a bit, "solutions" like this often hint at an ill-defined object lifecycle, which has other maintainability issues. It could be better if your objects implement `Closeable` or have a similar way for the code that uses them to declare that it's finished with them.
Problem
I'm more used to C++. To get a list of all instances of a class (this is a library class that can be extended by the user), I usually have a static container with all references to such objects: ``` #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; ``` How should I do the same in Java? I have a few concerns: - someone mentioned to me that there can be multiple classloaders, and that might cause problems - there is no destructor in java, so how would the references be removed from the list? - if the references are not removed, when do these objects get garbage-collected?