如何避免在 Java 中创建仅由内部 class 引用的对象?

How to avoid creating object only referenced by inner class in Java?

我正在尝试创建一些具有内部 class 的系统。我的代码可以总结成这样。

public abstract class A {
    public abstract void doSomething();
}

public class B {
    public final ArrayList<A> list=new ArrayList<A>();
    public B(){
    }
}

public class C {
    private int i;
    public C(B b){
        b.list.add(new A(){
            public void doSomething(){
                i++;
            }
        });
        b.list.add(new A(){
            public void doSomething(){
                System.out.println(i);
            }
        });
    }
}

public static void main (String[] arg) {
    B manager=new B();
    new C(manager);
    new C(manager);
    new C(manager);

}

A​​ 是抽象的 class 将作为内部 class 继承(在我的原始代码中它是监听器 class),B 是某种管理器 class保存 As 列表,C 保存数据,它的数据只能由其内部 class 修改或读取,并且在初始化时将 A 添加到 class B。代码本身工作正常。但问题是,会有各种各样的 C,比如 C2、C3,它们做不同的事情,这导致我的代码被数千个未分配的对象淹没 new C(manager);,这使得调试变得更加困难,代码看起来非常丑陋。所以在我看来,我的方法首先是错误的,但不知道如何避免这种情况。那么我应该如何改变我的方法来避免有数千个未分配的对象?

我的建议是:尽量不要使用构造函数来做依赖状态的操作(i)。使用静态函数,并将状态保存在单独的 class(我们称之为“上下文”)中。

import java.util.ArrayList;

public class Demo {

    // A
    abstract static class InnerListener {
        public abstract void onEvent();
    }
    
    // B
    static class ListenerManager {
        public final ArrayList<InnerListener> listeners = new ArrayList<InnerListener>();
    }

    static class SideEffectContext {
        public int i = 0;
    }
    // C
    static class ListenerUtil {
        public static void setupListeners(ListenerManager manager, SideEffectContext context) {
            manager.listeners.add(new InnerListener() {
                public void onEvent() {
                    context.i++;
                }
            });
            manager.listeners.add(new InnerListener() {
                public void onEvent() {
                    System.out.println(context.i);
                }
            });
        }
    }

    public static void main(String[] arg) {
        var manager = new ListenerManager();

        var ctxA = new SideEffectContext();
        var ctxShared = new SideEffectContext();

        ListenerUtil.setupListeners(manager, ctxA);
        ListenerUtil.setupListeners(manager, ctxShared);
        ListenerUtil.setupListeners(manager, ctxShared);
    }
}