当前位置:  开发笔记 > 编程语言 > 正文

是否需要删除Java侦听器?(一般来说)

如何解决《是否需要删除Java侦听器?(一般来说)》经验,为你挑选了2个好方法。

想象一下这个示例java类:

class A {
    void addListener(Listener obj);
    void removeListener(Listener obj);
}

class B {
    private A a;
    B() {
        a = new A();
        a.addListener(new Listener() {
            void listen() {}
        }
 }

我是否需要向B添加finalize方法以调用a.removeListener?假设A实例也将与其他一些对象共享,并且将比B实例更长.

我担心我可能会在这里创建垃圾收集器问题.什么是最佳做法?



1> janm..:

参考图中有一个循环.引用B和B引用A.垃圾收集器将检测周期并查看何时没有对A和B的外部引用,然后将收集两者.

试图在这里使用终结器是错误的.如果B被销毁,则对A的引用也将被删除.


声明:"假设A实例也将与其他一些对象共享,并且将比B实例更长." 是错的.唯一的方法是如果从终结器以外的某个地方明确地删除了监听器.如果传递对A的引用,那将意味着对B的引用,并且B将不会被垃圾收集,因为存在对AB循环的外部引用.


进一步更新:

如果要打破循环并且不要求B显式删除侦听器,则可以使用WeakReference.像这样的东西:

class A {
    void addListener(Listener obj);
    void removeListener(Listener obj);
}

class B {
    private static class InnerListener implements Listener {
        private WeakReference m_owner;
        private WeakReference m_source;

        InnerListener(B owner, A source) {
            m_owner = new WeakReference(owner);
            m_source = new WeakReference(source);
        }

        void listen() {
            // Handling reentrancy on this function left as an excercise.
            B b = (B)m_owner.get();
            if (b == null) {
                if (m_source != null) {
                    A a = (A) m_source.get();
                    if (a != null) {
                        a.removeListener(this);
                        m_source = null;
                    }
                }

                return;
            }
            ...
        }
    }

    private A a;

    B() {
        a = new A();
        a.addListener(new InnerListener(this, a));
    }
}

如果需要跨多个类可以进一步推广.


通过匿名的Listener子类,它包含对包含B实例的引用.
声明:"a.addListener(new Listener(){void listen(){}})"创建一个B的匿名内部类,它具有对B的引用.A通过内部类的实例引用B.
卫生署!忘记了anon类确实引用了它创建的实例.实时和学习...

2> workmad3..:

我对GC的理解是,在调用removeListener方法之前,类A将维护对侦听器的引用,因此它不会成为GC清理的候选者(因此不会调用finalize).

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有