我可以将 WeakReference 传递给 Observable 监听器吗?

Can I pass WeakReference to the Observable listeners?

我正在修复遗留应用程序,该应用程序存在对象被 class 实现 Observable 中的观察者列表保留的问题。正确移除观察者将是一项漫长的任务,所以我想我可以使用 WeakReference 来克服这个问题。问题是,调用 Observable.addObserver(new WeakReference(something)) 是不可能的,因为 WeakReference 没有实现 Observer。所以我想像这样创建名为 WeakObserver 的 class:

public class WeakObserver<T> extends WeakReference<T> implements Observer {
private T observer;

public WeakObserver(final T observer){
    super(observer);
    this.observer = observer;
}

@Override
public void update(Observable o, Object arg) {
    ((Observer)observer).update(o, arg);
}
}

这里的问题很明显 - 除了 update 方法中的不安全转换之外,我正在创建另一个对我想要收集垃圾的对象的引用。

这样的事情有可能吗,还是我想做一些愚蠢的事情?

(以我的评论为基础)您可以依赖 WeakReference 的 get 方法,而不是保留引用。 class 也可以参数化,因此更新方法中不需要强制转换:

private class ObserverWeak extends WeakReference<Observer> implements Observer{

    public ObserverWeak(Observer referent) {
        super(referent);
    }

    @Override
    public void update(Observable obs, Object arg) {
        if ( super.get() != null ){
            super.get().update(obs, arg);
        }
    }


}

你或许可以完成这项工作,但你希望你的弱可观察对象具有对真实Observable的弱引用,而不是 弱引用。

此外,仅让真正的观察者被 GC 是不够的;一旦发生这种情况,您还需要从 Observable 注销包装器对象。这种事情就是参考队列的用途,但是如果你不想修改 Observable class 那么你可以像这样快捷方式:

public class WeakObserver implements Observer {
    private final WeakReference<Observer> observer;
    private final Observable observed;

    public WeakObserver(Observer observer, Observable observed){
        this.observer = new WeakReference<Observer>(observer);
        this.observed = observed;
    }

    @Override
    public void update(Observable o, Object arg) {
        Observer realObserver = observer.get();

        if (realObserver != null) {
            realObserver.update(o, arg);
        } else {
            observed.deleteObserver(this);
        }
    }
}

WeakObserver 特定于单个 Observable,当底层真实 Observer 被 GC 时,有必要将其自动删除。如果您愿意并且能够适当地修改 Observable,则可以通过使用 ReferenceQueue 来避免这种情况。