2015-03-09 3 views
1

Может ли кто-нибудь сказать мне, как подсчитать количество экземпляров класса?Как подсчитать количество экземпляров класса

Вот мой код

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 

переменная класса должны использоваться, чтобы подсчет количества экземпляров класса велосипедов, созданный и класс тестера создает ряд экземпляров класса велосипедов и демонстрирует работы класса Bicycle и переменной класса. Я посмотрел по всему Интернету, и я не могу ничего найти, может кто-нибудь показать мне, как это сделать, пожалуйста, заранее спасибо :)

+4

Посмотрите на 'static' (т.е. класс). – Mena

+1

Этот подкласс Variable фактически ничего не делает.Похоже, вы ищете структуру данных для отслеживания экземпляров своего класса. Это будет нечто, что было бы вне вашего класса, например, java [объекты коллекции] (http://www.tutorialspoint.com/java/java_collections.htm). Для этой цели также могут использоваться переменные статического класса. – JNYRanger

ответ

11

Поскольку static переменные инициализируются только один раз, и они распределяются между всеми экземплярами, вы можете:

class MyClass { 

    private static int counter; 

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

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

Подробнее о static полей в JLS - 8.3.1.1. static Fields:

Если A поле объявлено static, существует ровно одно воплощение поля, независимо от того, сколько экземпляров (возможно, ноль) класса может иметь значение Будет создано. Поле static, иногда называемое переменной класса, воплощается при инициализации класса (§12.4).

Обратите внимание, что counter неявно устанавливается в ноль

+0

Лучше сделать 'getNumOfInstances()' be 'static'. –

1

Почему бы не использовать статический счетчик?

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

Метод 'countInstances()' более корректно будет 'static'. –

+0

в зависимости от философии вашего приложения –

+0

Число экземпляров - это свойство класса, а не какого-либо конкретного экземпляра, независимо от того, как вы пишете имя метода доступа. Следовательно, этот аксессор должен быть классом. Это вопрос согласованности дизайна. Как практический вопрос, он позволяет определить, сколько экземпляров было создано, не имея одного в руке. С его помощью в качестве метода экземпляра я могу заставить это сделать: 'int numInstances = new Bicycle(). CountInstances() - 1;'. Это уродство возникает из-за неправильного дизайна. –

0

Одной из основных подхода состоит в том, чтобы объявить статические числовые поля член то будет увеличиваться каждый раз, когда вызывается конструктор.

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

Вам просто нужен статический счетчик в классе.

public class Bicycle { 
    private static volatile int instanceCounter; 

    public Bicycle() { 
     instanceConter++; 
    } 

    public static int getNumOfInstances() { 
     return instanceCounter; 
    } 

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

Как уже упоминалось во многих комментариях finalize() не рекомендуется использовать, так что может быть другой подход к подсчету экземпляров велосипедов -

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

Нет, нет, НЕТ! Не переопределяйте 'finalize()'. Не. Не разрабатывайте привычку, не рекомендуйте ее другим, не передавайте ее в обзорах кода. Он может иметь вредные эффекты (например, объекты, живущие дольше, чем они были бы в противном случае), и это, как правило, не гарантирует, что поведение, которое вы, вероятно, ожидаете. –

+1

Согласен !. Хотя я думаю, что это не было вредно для использования finalize() в этом конкретном случае, но да, вы правы, это не рекомендуемое решение. Поэтому я изменил свой ответ другим методом подсчета экземпляров. – hemant1900

2

Кроме того, вы должны переопределить метод Finalize, чтобы уменьшить счетчик

public class Bicycle { 
... 
    public static int instances = 0; 

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

    @Override 
    protected void finalize() { 
     super.finalize(); 
     --instances; 
    } 

} 

Вы должны иметь в виду, что статические переменные являются областью действия CLASS (для каждого экземпляра нет ни одного экземпляра, только для каждого класса)

Тогда вы могли бы продемонстрировать экземпляра декремент с:

... 
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. НИКОГДА не переопределяйте 'finalize()', если вы можете избежать этого. Вероятно, это не слишком вредно в этом простом контексте, но вы действительно не должны развивать привычку. Обратите внимание, что в этом случае есть альтернатива, включающая фантомные ссылки (что намного сложнее, чем я предполагаю, ожидается). Обратите также внимание на то, что объект может существовать после вызова его метода 'finalize()', поэтому использование 'finalize()' таким образом даже не гарантировано в целом. –

1

Pleae попробовать инструмент Java

jmap -histo <PDID> 

Out положить

 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 
Смежные вопросы