2015-03-09 1 views
1

Quelqu'un peut-il me dire comment compter le nombre d'instances d'une classe?Comment compter le nombre d'instances d'une classe

Voici mon code

public class Bicycle { 

    //instance variables 
    public int gear, speed, seatHeight; 
    public String color; 

    //constructor 
    public Bicycle(int gear, int speed, int seatHeight, String color) { 
     gear = 0; 
     speed = 0; 
     seatHeight = 0; 
     color ="Unknown";  
    } 

    //getters and setters 
    public int getGear() { 
     return gear; 
    } 
    public void setGear(int Gear) { 
     this.gear = Gear; 
    } 

    public int getSpeed() { 
     return speed; 
    } 
    public void setSpeed(int Speed){ 
     this.speed = Speed; 
    } 

    public int getSeatHeight() { 
     return seatHeight; 
    } 
    public void setSeatHeight(int SeatHeight) { 
     this.seatHeight = SeatHeight; 
    } 

    public String getColor() { 
     return color; 
    } 
    public void setColor(String Color) { 
     this.color = Color; 
    } 

}//end class 



public class Variable extends Bicycle { 

    public Variable(int gear, int speed, int seatHeight, String color) { 
     super(gear, speed, seatHeight, color); 

    } 

}//end class 


public class Tester { 

    public static void main(String args[]){ 


     Bicycle bicycle1 = new Bicycle(0, 0, 0, null); 
     bicycle1.setColor("red"); 
     System.out.println("Color: "+bicycle1.getColor()); 
     bicycle1.setSeatHeight(4); 
     System.out.println("Seat Height: "+bicycle1.getSeatHeight()); 
     bicycle1.setSpeed(10); 
     System.out.println("Speed: "+bicycle1.getSpeed()); 
     bicycle1.setGear(6); 
     System.out.println("Gear: "+bicycle1.getGear()); 

     System.out.println("");//space 

     Bicycle bicycle2 = new Bicycle(0, 0, 0, null); 
     bicycle2.setColor("black"); 
     System.out.println("Color: "+bicycle2.getColor()); 
     bicycle2.setSeatHeight(6); 
     System.out.println("Seat Height: "+bicycle2.getSeatHeight()); 
     bicycle2.setSpeed(12); 
     System.out.println("Speed: "+bicycle2.getSpeed()); 
     bicycle2.setGear(6); 
     System.out.println("Gear: "+bicycle2.getGear()); 

     System.out.println("");//space 

    }//end method 
}//end class 

La variable de classe doit être utilisé pour tenir le compte du nombre d'instances de la classe de vélos créé et la classe de testeur crée un certain nombre d'instances de la classe de bicyclette et démontre la fonctionnements de la classe Bicycle et de la variable de classe. J'ai regardé partout sur Internet et je n'arrive pas à trouver quelque chose, quelqu'un pourrait me montrer comment le faire s'il vous plaît, merci d'avance :)

+4

Regardez dans 'static' (à savoir champs de portée). – Mena

+1

Cette variable de sous-classe ne fait réellement rien.Il semble que vous cherchiez une structure de données pour suivre les instances de votre classe. Ce serait quelque chose qui serait en dehors de votre classe, comme java [collection objets] (http://www.tutorialspoint.com/java/java_collections.htm). Les variables de classe statique peuvent également être utilisées à cette fin. – JNYRanger

Répondre

11

Depuis static variables initialisées une seule fois, et ils sont partagés entre tous les cas, vous pouvez:

class MyClass { 

    private static int counter; 

    public MyClass() { 
     //... 
     counter++; 
    } 

    public static int getNumOfInstances() { 
     return counter; 
    } 
} 

En savoir plus sur static champs dans le JLS - 8.3.1.1. static Fields:

Si une champ est déclaré static, il existe exactement une incarnation du champ, quel que soit le nombre d'instances (éventuellement zéro) de la classe peut eventua Peut être créé. Un champ static, parfois appelé variable de classe, est incarné lors de l'initialisation de la classe (§12.4).

Notez que counter est implicitement mis à zéro

+0

Mieux vaut faire 'getNumOfInstances()' être 'static'. –

1

pourquoi ne pas utiliser un compteur statique?

public class Bicycle { 

    private static int instanceCounter = 0; 

    //instance variables 
    public int gear, speed, seatHeight; 
    public String color; 

    //constructor 
    public Bicycle(int gear, int speed, int seatHeight, String color) { 
     gear = 0; 
     speed = 0; 
     seatHeight = 0; 
     color ="Unknown";  
instanceCounter++; 
    } 

    public int countInstances(){ 
     return instanceCounter; 
    } 

........ 
+0

La méthode 'countInstances()' devrait être plus statique. –

+0

en fonction de la philosophie de votre application –

+0

Le nombre d'instances est une propriété de la classe, et non d'une instance spécifique, quelle que soit la manière dont vous épelez le nom de la méthode accesseur. Cet accesseur devrait donc être une méthode de classe. C'est une question de cohérence de conception. En pratique, cela vous permet de déterminer combien d'instances ont été créées sans en avoir une en main. Avec cela comme une méthode d'instance, je peux être forcé de faire ceci: 'num numInstances = new Bicycle(). CountInstances() - 1;'. Cette laideur provient d'un design imparfait. –

0

Une approche de base est de déclarer un thats champ membre numériques statiques incrémentés chaque fois que le constructeur est invoqué.

public class Bicycle { 

    //instance variables 
    public int gear, speed, seatHeight; 
    public String color; 
    public static int bicycleCount = 0; 

    //constructor 
    public Bicycle(int gear, int speed, int seatHeight, String color) { 
     gear = 0; 
     speed = 0; 
     seatHeight = 0; 
     color ="Unknown"; 
     bicycleCount++;  
    } 
    ... 
    } 
0

Vous avez juste besoin d'un compteur statique en classe.

public class Bicycle { 
    private static volatile int instanceCounter; 

    public Bicycle() { 
     instanceConter++; 
    } 

    public static int getNumOfInstances() { 
     return instanceCounter; 
    } 

    protected void finalize() { 
     instanceCounter--; 
    } 
} 

Comme mentionné dans de nombreux commentaires finalize() est recommandé de ne pas utiliser donc il pourrait y avoir une autre approche pour compter les instances de bicyclette -

public class Bicycle { 

    private static final List<PhantomReference<Bicycle>> phantomReferences = new LinkedList<PhantomReference<Bicycle>>(); 
    private static final ReferenceQueue<Bicycle> referenceQueue = new ReferenceQueue<Bicycle>(); 
    private static final Object lock = new Object(); 
    private static volatile int counter; 
    private static final Runnable referenceCleaner = new Runnable() { 
     public void run() { 
      while (true) { 
       try { 
        cleanReferences(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }; 

    static { 
     Thread t = new Thread(referenceCleaner); 
     t.setDaemon(true); 
     t.start(); 
    } 

    private Bicycle() { 
    } 

    public static Bicycle getNewBicycle() { 
     Bicycle bicycle = new Bicycle(); 
     counter++; 
     synchronized (lock) { 
      phantomReferences.add(new PhantomReference<Bicycle>(new Bicycle(), referenceQueue)); 
     } 
     System.out.println("Bicycle added to heap, count: " + counter); 
     return bicycle; 
    } 

    private static void cleanReferences() { 
     try { 
      PhantomReference reference = (PhantomReference) referenceQueue.remove(); 
      counter--; 
      synchronized (lock) { 
       phantomReferences.remove(reference); 
      } 
      System.out.println("Bicycle removed from heap, count: " + counter); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static int getNumOfBicycles() { 
     return counter; 
    } 
} 

public class BicycleTest { 

    public static void main(String[] args) { 
     int i = 0; 
     while (i++ < 1000) { 
      Bicycle.getNewBicycle(); 
     } 
     while (Bicycle.getNumOfBicycles() > 0) { 
      try { 
       Thread.sleep(1000); 
       System.gc(); // just a request 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
+1

Non, non, NON! Ne pas surcharger 'finalize()'. Ne pas. Ne développez pas l'habitude, ne le recommande pas à d'autres, ne lui donnez pas une passe dans les revues de code. Il peut avoir des effets néfastes (par exemple, des objets qui vivent plus longtemps qu'ils ne le feraient autrement), et en général, il n'est pas garanti qu'il conduise au comportement auquel vous vous attendez probablement. –

+1

D'accord! Bien que je pense que ce n'était pas si dangereux d'utiliser finalize() dans ce cas particulier, mais oui, vous avez raison, ce n'est pas une solution recommandée. J'ai donc modifié ma réponse avec une autre approche pour compter les instances. – hemant1900

2

En outre, vous devez remplacer méthode finalize pour décrémenter le compteur

Vous devez garder à l'esprit que les variables statiques ont une portée CLASS (il n'y en a pas pour chaque instance, une seule par classe)

Ensuite, vous pouvez démontrer décrémentation exemple avec:

... 
System.out.println("Count:" + Bicycle.getNumOfInstances()); // 2 
bicycle1 = null; 
bicycle2 = null; 
System.gc(); // not guaranteed to collect but it will in this case 
Thread.sleep(2000); // you expect to check again after some time 
System.out.println("Count again:" + Bicycle.getNumOfInstances()); // 0 
+1

Yuck. Ne remplacez JAMAIS 'finalize()' si vous pouvez éventuellement l'éviter. Ce n'est probablement pas trop dangereux dans ce contexte simple, mais vous ne devriez vraiment pas développer cette habitude. Notez en outre que dans ce cas, il existe une alternative impliquant des références fantômes (ce qui est plutôt beaucoup plus sophistiqué que je ne le suppose). Notez aussi qu'il est possible pour un objet de survivre à l'invocation de sa méthode 'finalize()', donc utiliser 'finalize()' de cette façon n'est même pas, en général, garanti pour fonctionner. –

1

Pleae essayer l'outil de java

jmap -histo <PDID> 

eteint

 num  #instances   #bytes class name 
---------------------------------------------- 
    1:  1105141  97252408 java.lang.reflect.Method 
    2:  3603562  86485488 java.lang.Double 
    3:  1191098  28586352 java.lang.String 
    4:  191694  27035744 [C