匿名监听器是否与弱引用不兼容?

我正在读这个刚问的问题: 避免回调中的内存泄漏?

我很困惑,直到有人回答以下问题:

“这种方法的问题是你不能有一个只在集合中引用的监听器,因为它会随机消失(在下一个GC上)”

我是否理解使用弱引用(如存储在WeakHashMap中)与匿名侦听器不兼容?

我通常传递这样的听众:

public static void main(String[] args) { final Observable obs = new SomeObservable(); obs.addObserver(new Observer() { public void update(final Observable o, final Object arg) { System.out.println("Notified"); } }); obs.notifyObservers(); ... // program continues its life here } private static final class SomeObservable extends Observable { @Override public void addObserver(final Observer o) { super.addObserver(o); setChanged(); // shouldn't be done from here (unrelated to the question) } } 

我使用CopyOnWriteArrayList跟踪监听器(上面的默认Observable显然使用了一个旧的Vector,但它只是一个示例来说明我通常如何创建一个匿名类来用作监听器)。

作为一个额外的问题:如果可观察的主题使用WeakHashMap,那么对匿名监听器的引用何时才符合GC的条件? 当主要方法退出时? 一旦obs.addObserver调用结束了吗?

我对于保存/存储/忽略对GC的匿名类实例的引用的位置/方式/时间有点困惑。

显然,如果我保持一个正常的引用它不符合GC的条件,但是当它在WeakHashMap中时,究竟什么时候听众变得对GC有效?

是的,你是对的,一个可监听的类,用弱引用来维护监听器(WeakHashMap也是如此)需要它们的独立持久性。 可用于侦听器具有子级和父级的侦听器层次结构。

对于非WeakReference用法,必须调用显式的removeListener。 除非侦听器对象可以与可听对象一样长。 在大多数用例中都很好,而匿名类也可以。

对于匿名类实例,只有在访问类主体外部的最终对象时才会发生泄漏 (GC预防)。

注意:WeakHashMap ia对其自己的Map.Entry子类使用弱引用。 这有时可能令人难以置信。

如果一个对象只是WeakHashMap的一个键,那么它就有资格并且可能在下一个GC上清理掉。

使用Weak引用集合的整个想法是隐式删除不再引用的侦听器。 (这可以避免内存泄漏的可能性)问题是可以在“随机”时间点过早地删除监听器。