Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: how to store references to all instances of a class?

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?
like image 606
Eduardo Bezerra Avatar asked Apr 09 '13 16:04

Eduardo Bezerra


People also ask

How do I limit the number of instances of a class?

By making our constructor private and then creating a visible constructor method, we can limit the number of instance creations (like we do in singleton design pattern) or recycle instances or other construction-related tasks. Doing new x() never returns null, but using the factory pattern, you can return null.

Can two objects have same reference in Java?

No, it never returns true unless you feed it the same exact object reference. The reason for it is that Java objects are not "embedded" in one another: there is a reference to B inside A , but it refers to a completely different object.

How do you reference a class in Java?

In java, this is a reference variable that refers to the current object. super is used to refer immediate parent class instance variable. We can use the super keyword to access the data member or field of the parent class. It is used if parent class and child class have the same fields.

Can a class have multiple instances?

You can always create multiple instances of a class! This is what classes are designed for! Each object will hold its own individual inner variables (unless they are static, in which case they are shared). If you wish to pass a list of categories to a function, or return a list of categories.

What is the difference between class and instance in Java?

Instances in Java are known as Objects. An object is a real-life entity, whereas a Class is a group of similar objects. An object is created from the class. Dog is a class that is a real-life entity. Basically, instance and object are the same thing. We create an instance of the Dog class using the new keyword.

What is the use of reference type in Java?

Classes, interfaces, arrays, enumerations, and, annotations are reference types in Java. Reference variables hold the objects/values of reference types in Java. 3. Reference variable can also store null value. By default, if no object is passed to a reference variable then it will store a null value. 4.

Do we need a list of all instances of a class?

It is not very common to need a list of all the instances of a given class, and having one would cause all sorts of design problems (because now even instances created in totally unrelated contexts depend on each other through this list). – tdammers Jun 11 '13 at 8:27 1 "iterate through them for various purposes" ... such as ... ?

What is the difference between class and object in Java?

In Java, Class and Object are the basic concepts of Object-Oriented Programming. Class is a blueprint from which objects are created. Instances in Java are known as Objects. An object is a real-life entity, whereas a Class is a group of similar objects. An object is created from the class. Dog is a class that is a real-life entity.


2 Answers

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.

like image 80
yshavit Avatar answered Oct 01 '22 10:10

yshavit


Rather than storing a reference to an object, store a WeakReference to the object - this way the garbage collector will free the object if the WeakReference is the only reference that remains.

like image 38
Zim-Zam O'Pootertoot Avatar answered Oct 01 '22 10:10

Zim-Zam O'Pootertoot