count class instances for every derived class

前端 未结 7 1977
栀梦
栀梦 2021-02-19 09:09

is there any way to make all derived classes count their instances?How (write code in one of C++, C#, Java)?

Imagine I\'ve got access to the root class (e.g. object), an

7条回答
  •  独厮守ぢ
    2021-02-19 09:34

    In Java you can use a global Multiset:

    import com.google.common.collect.ConcurrentHashMultiset;
    
    public abstract class InstanceCounted {
    
        protected InstanceCounted() {
            COUNT_MAP.add(this.getClass());
        }
    
        protected static final ConcurrentHashMultiset> COUNT_MAP =
            ConcurrentHashMultiset.create();
    
    }
    

    Alternatively you can use a Map if you don't want the dependency on guava.

    Note: this only tracks instance creation, not garbage collection, so the count will never decrease. You can also track collection using PhantomReferences if you are willing to take a performance hit:

    import java.lang.ref.PhantomReference;
    import java.lang.ref.Reference;
    import java.lang.ref.ReferenceQueue;
    
    import com.google.common.collect.HashMultimap;
    import com.google.common.collect.Multimap;
    import com.google.common.collect.Multimaps;
    
    public abstract class InstanceCounted {
    
        public static int getInstanceCount(Class clazz) {
            reap();
            return INSTANCES.get(clazz).size();
        }
    
        protected InstanceCounted() {
            reap();
            INSTANCES.put(getClass(), new CountingReference(this));
        }
    
        static final Multimap, CountingReference> INSTANCES =
            Multimaps.synchronizedSetMultimap(HashMultimap., CountingReference>create());
    
        static final ReferenceQueue QUEUE =
            new ReferenceQueue();
    
        private static void reap() {
            Reference ref;
            while ((ref = QUEUE.poll()) != null) {
                ((CountingReference) ref).clear();
            }
        }
    
        private static class CountingReference extends PhantomReference {
    
            public void clear() {
                super.clear();
                INSTANCES.remove(clazz, this);
            }
    
            CountingReference(InstanceCounted instance) {
                super(instance, QUEUE);
                this.clazz = instance.getClass();
            }
    
            private final Class clazz;
    
        }
    
    }
    

提交回复
热议问题