web-dev-qa-db-ja.com

クラスのインスタンスの数を数える方法

クラスのインスタンスの数を数える方法を誰かに教えてもらえますか?

これが私のコードです

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クラスのインスタンスの数をカウントするために使用され、テスタークラスはBicycleクラスのインスタンスの数を作成し、Bicycleクラスとクラス変数の働きを示します。私はインターネット全体を調べましたが、何も見つからないようです。誰かに教えてくれますか。事前に感謝します:)

6
RifferRaffers

static変数は1回だけ初期化され、すべてのインスタンス間で共有されるため、次のことができます。

class MyClass {

    private static int counter;

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

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

JLS-8.3.1.1。static Fieldsstaticフィールドの詳細をご覧ください。

フィールドがstaticとして宣言されている場合、クラスのインスタンス(おそらく0)がいくつ作成されても、フィールドの具体化は1つだけ存在します。クラス変数と呼ばれることもあるstaticフィールドは、クラスの初期化時に実装されます(§12.4)。

counterは暗黙的にゼロに設定されることに注意してください

18
Maroun

Javaのツールを試してください

jmap -histo <PDID>

アウト

     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
7
Lee Tuấn

さらに、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です(インスタンスごとに1つではなく、クラスごとに1つだけ)。

次に、インスタンスのデクリメントを次のように示すことができます。

...
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
3
Danilo Gomes

または、 初期化ブロック と静的変数を使用してカウンターを作成できます。

class SomeClass
{
    static int counter;
    {
         counter++;
    }
}

初期化ブロックはコンパイラーによってすべてのコンストラクターにコピーされるため、必要なコンストラクターの数に関係なく、一度作成する必要があります(上記のリンクを参照)。 {}のブロックは、クラスの新しいオブジェクトを作成するたびに実行され、変数カウンターを1つ増やします。そしてもちろん、次のような方法でカウンターを取得します。

public int getCounter()
{
    return counter;
}

または直接

int numOfInstances = SomeClass.counter;
1
Alexandros

なぜ静的カウンタを使用しないのですか?

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;
    }

........
1
Matteo Rubini

クラスに静的カウンターが必要なだけです。

_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();
            }
        }
    }
}
_
0
hemant1900

基本的なアプローチの1つは、コンストラクターが呼び出されるたびに増分される静的な数値メンバーフィールドを宣言することです。

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
Amir Afghani