java中运行时存在一个类的实例数

时间:2010-08-13 16:20:38

标签: java

今天在我的采访中,我被要求编写一个代码来确定一个类在java中运行时退出的实例数。

我告诉他们,我们可以使用反射。如果你有有效的方法,请告诉我。

3 个答案:

答案 0 :(得分:5)

我认为反思不会对你有所帮助。有JVMTI(以及旧的和现已不存在的JVMPI)可用于分析堆并确定类的当前实例数。

编码的替代方法是向要跟踪实例的类添加计数器:

class Myclass {

   static private final AtomicInteger count = new AtomicInteger();

   {
      count.getAndIncrement();
   }

   static public int instanceCount() { 
      return count.get();
   }

   // edit: account for serializable
   private void readObject(ObjectInputStream ois) 
       throws ClassNotFoundException, IOException {
      counter.getAndIncrement();
      ois.defaultReadObject();          
   }
}

这将跟踪有史以来创建的实例数,并且是线程安全的。要找出实例被垃圾收集的时间,您可以使用PhantomReferenceReferenceQueue来跟踪收集的实例并减少计数器。

class Myclass {

   static private final AtomicInteger count = new AtomicInteger();
   static private final ReferenceQueue<MyClass> queue = new ReferenceQueue<MyClass>();

   {
      count.getAndIncrement();
      new PhantomReference<MyObject>(this, queue);
   }

   static public int instanceCount() { 
      return count.get();
   }

   static {
      Thread t = new Thread() {
         public void run() {
            for (;;) {
               queue.remove();
               count.decrementAndGet();
            }
         }
      };
      t.setDaemon(true);
      t.start();
   }

}

编辑:

如果类是可序列化的,请实现readObject方法并递增计数器。我已将此添加到第一个代码示例中。

答案 1 :(得分:1)

我认为你不能用反射来做任意一个类。可能他只是希望你添加一个静态计数器字段:

public class Foo
{
  private static int counter = 0;
  public Foo()
  {
    counter++;
  }   
}

答案 2 :(得分:1)

如果通过提供访问器方法和私有构造函数(如Singleton模式)来限制实例生成,那么您可以继续计算创建新实例的次数。