Java 如何计算类的实例数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28947571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:03:35  来源:igfitidea点击:

How to Count Number of Instances of a Class

javavariablesinstances

提问by RifferRaffers

Can anyone tell me how to count the number of instances of a class?

谁能告诉我如何计算一个类的实例数?

Here's my 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

The class variable is to be used to keep count of the number of instances of the Bicycle class created and the tester class creates a number of instances of the Bicycle class and demonstrates the workings of the Bicycle class and the class variable. I've looked all over the internet and I can't seem to find anything, could someone show me how to do it please, thanks in advance :)

类变量用于记录创建的 Bicycle 类的实例数量,测试类创建了 Bicycle 类的多个实例,并演示了 Bicycle 类和类变量的工作原理。我已经在互联网上查看了所有内容,但似乎找不到任何东西,有人可以告诉我该怎么做,在此先感谢:)

采纳答案by Maroun

Since staticvariables initialized only once, and they're shared between all instances, you can:

由于static变量仅初始化一次,并且它们在所有实例之间共享,因此您可以:

class MyClass {

    private static int counter;

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

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

Read more about staticfields in the JLS - 8.3.1.1. static Fields:

阅读有关JLS 中static字段的更多信息- 8.3.1.1。静态字段

If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A staticfield, sometimes called a class variable, is incarnated when the class is initialized (§12.4).

如果声明了一个字段static该字段只存在一个化身,无论最终可能创建多少个类的实例(可能为零)。一个static字段,有时也称为类变量,在类初始化时被体现(第 12.4 节)。

Note that counteris implicitly set to zero

请注意,counter隐式设置为零

回答by Matteo Rubini

why not using a static counter?

为什么不使用静态计数器?

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

........

回答by Amir Afghani

One basic approach is to declare a static numeric member field thats incremented each time the constructor is invoked.

一种基本方法是声明一个静态数字成员字段,每次调用构造函数时都会增加该字段。

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

回答by hemant1900

You just need static counter in class.

你只需要在课堂上使用静态计数器。

public class Bicycle {
    private static volatile int instanceCounter;

    public Bicycle() {
        instanceConter++; 
    }

    public static int getNumOfInstances() {
        return instanceCounter;
    }

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

As mentioned in many comments finalize()is not recommended to use so there could be another approach to count the Bicycle instances -

正如许多评论中提到的,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();
            }
        }
    }
}

回答by Danilo Gomes

In addition, you should override finalize method to decrement the counter

此外,您应该覆盖 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;
    }

}

You should have in mind that static variables are CLASS scoped (there is no one for each instance, only one per class)

您应该记住,静态变量是 CLASS 范围的(每个实例没有一个,每个类只有一个)

Then, you could demonstrate instance decrement with:

然后,您可以使用以下方法演示实例递减:

...
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

回答by Lee Tu?n

Pleae try the tool of java

请试试java的工具

jmap -histo <PDID>

Out put

输出

     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

回答by Alexandros

Alternatively, you can create a counter with an initializer blockand a static variable.

或者,您可以创建一个带有初始化程序块和静态变量的计数器。

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

Initializer blocks get copied by the compiler into every constructor, so, you will have to write it once no matter how many constructors you will need (As referred into the above link). The block in {} runs every time you create a new object of the class and increases the variable counter by one. And of course get the counter by something like:

初始化器块被编译器复制到每个构造函数中,因此,无论您需要多少个构造函数,您都必须编写一次(如上述链接中所述)。每次您创建类的新对象并将变量 counter 增加 1 时,{} 中的块都会运行。当然,通过以下方式获取计数器:

public int getCounter()
{
    return counter;
}

or directly

或直接

int numOfInstances = SomeClass.counter;

回答by user10424029

public class Number_Objects {

    static int count=0;
    Number_Objects(){
        count++;
    }

    public static void main(String[] args) {

        Number_Objects ob1=new Number_Objects();
        Number_Objects ob2=new Number_Objects();
        Number_Objects obj3=new Number_Objects();
        System.out.print("Number of objects created :"+count);
    }

}