How to know how many objects were instantiated?

5

In a Java application, how do I know how many objects in a class were instantiated? This doubt came to me by reading the article mentioned in the link below. Here is the excerpt that gave me the doubt:

  

2.4 - Connection Factory

     

At some point in our application, we would like to have the   control over the construction of our class objects. A lot can   be done through the constructor, how to know how many objects were   instantiated or log on to these instantiations.

Source: Caelum

    
asked by anonymous 05.11.2015 / 13:49

3 answers

6

You will create a static member in the class that will save the instance counter.

In the constructor will increment this counter.

Just need to know how many have been instantiated or need to know how many are instantiated? If you need the second, you must decrease the counter when the object is destroyed or made available.

If it is to be decremented in the destruction, it will probably be done in the finalize() method. If you need to do this when it is no longer used, the decrease must occur in the dispose() method or something similar that is called whenever it is made available. Or you can use the java.lang.AutoCloseable interface in the class and use the object to ensure that it is called, such as the try with resources .

Example:

public class teste {
    protected static int count = 0;
    public teste() {
        count++;
    }
    protected void finalize() throws Throwable {
        count--;
    } 
    public static int getInstanceCount() {
        return count;
    }
}

Obviously this is a simplistic implementation and will have problems in a multithreaded environment.

This operation is not atomic. You can have a thread reading the counter, let's assume that the counter is worth 1. Then another thread also reads the counter that is still worth 1. The first / em> does increment and it passes value 2. The second thread does the same and it passes value 2. But if before it was 1 then had an instance, now two new instances were created by 2 < in concurrent threads, totaling 2 instances, but the counter is worth 2. The same occurs in the decrement, counting less than it should.

To solve this would have to create some form of locking, ensuring that the operation is atomic.

    
05.11.2015 / 14:04
2

In Java there is a modifier called static that makes the values / methods in the class scope, not the instance, so you can easily create a public static int contadorInstancias = 0; variable and increment it whenever the constructor is used.

You can get more information about static here: link

    
05.11.2015 / 14:03
2

First of all you should understand that a Fábrica de Conexões is nothing more than a class that will perform the creation of objects for you, so you can use the adopted strategy in almost 100% of the cases with the static modifier.

The STATIC modifier

This modifier is for a method or property to be relative to CLASS and not to the instantiated OBJECT. Example: let's say that in a class ObjectFactory has the following structure

public class ObjectFactory {
    private static int counter;
    private static ObjectFactory instance;

    public static object createInstance(TargetEnum target) {
        // ... lógica para instanciar a classe alvo
        counter++; // <-- aumentar o contador de objetos criados (este aqui não separa por tipo de objeto)
        // retornar o objeto instanciado.
    }

    // Retorna a quantidade de objetos instanciados
    public static int getQuantidadeObjetosInstanciados() {
        return counter;
    }

    public static ObjectFactory getInstance() {
        if (instance == null)
            instance = new ObjectFactory();
        return instance;
    }
}

Following this idea above the class can accomplish two things. The first is that whenever you use the getInstance method it will always return the same object regardless of how many times you call.

ObjectFactory obj1 = ObjectFactory.getInstance();
ObjectFactory obj2 = ObjectFactory.getInstance();

// obj1 === obj2 - sempre irá resultar em true e alteração em um alterará o outro também

The second is using getQuantidadeObjetosInstanciados which will always show the value of the instantiated elements

// ObjectFactory counter = 0
TargetClass objAlvo = ObjectFactory.createInstance(TargetEnum.TargetClass);
int qtdInstances = ObjectFactory.getQuantidadeObjetosInstanciados();
// qtdInstances = 1
TargetClass objAlvo2 = ObjectFactory.createInstance(TargetEnum.TargetClass);
int qtdInstances = ObjectFactory.getQuantidadeObjetosInstanciados();  
// qtdInstances = 2

You can combine them and everything else, but it is important to remember that in finalize of class it would be good for you to decrease the counter.

    
05.11.2015 / 14:22