Java: how to store references to all instances of a class?
I'm used to C. to get a list of all instances of a class (this is a library class that can be extended by users), I usually have a static container that contains all references to these 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 can I do the same thing in Java? I have some concerns:
>Someone mentioned to me that there may be multiple class loaders, which may lead to the problem > there is no destructor in Java, so how to remove the reference from the list? > If the reference is not deleted, when will these objects be garbage collected?
Solution
Simple thing: multiple classloaders won't cause problems unless you use non - standard delegate mode (using custom classloaders) If you do have such a non-standard class loader, you can get a situation that different parts of the application use different versions of CppClass class (each version comes from a different classloader) There are various problems (you can get a ClassCastException conversion from CppClass to CppClass!), But it should not affect your static collection; Each CppClass has its own independent set
Next: do not add objects to the collection from the constructor Leaking this reference from the constructor may cause memory model problems Instead, you should create a static factory method to create objects, and then add them separately to the static collection Of course, the collection should also be thread safe
Finally, the core issue If each object is not equal to any other object (that is, if you do not override object. Equals), you can use weakhashmap with the object as the key If the class does override the equal sign, you can create a collection of weakreferences that you can cut at your convenience (when inserting, when retrieving lists, etc.) WeakReference does not prevent the object it refers to from being GCed - it only returns null from get after GC occurs
However, if I can do a little editing, a "solution" like this usually implies an ill defined object life cycle, which creates other maintainability problems It may be better if your object implements closeable, or if you have a similar way to declare that it has been completed for the code that uses them