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

时间:2015-03-25 18:06:18

标签: java observer-pattern weak-references

我正在修复遗留应用程序,该应用程序在实现Observable的类中被观察者列表保留的对象存在问题。正确删除观察者将是一项冗长的任务,所以我认为我可以使用WeakReference来克服这个问题。问题是,由于Observable.addObserver(new WeakReference(something))没有实现Observer,因此无法调用WeakReference。所以我想要创建一个名为WeakObserver的类,如下所示:

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方法中不安全的强制转换之外,我正在创建另一个对象,我想要收集垃圾。

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

2 个答案:

答案 0 :(得分:2)

(构建我的评论)您可以依赖WeakReference的get方法,而不是保留引用。该类也可以进行参数化,因此在更新方法中不需要强制转换:

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);
        }
    }


}

答案 1 :(得分:1)

你可能可以做到这一点,但是你希望你的弱观察者能够对真实的Observable进行弱引用,而不是弱引用。

此外,仅仅允许真正的观察者进行GC测量是不够的;一旦发生这种情况,您还需要从Observable取消注册包装器对象。这类是参考队列的用途,但是如果您不想修改Observable类,那么您可以像这样快捷方式:

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时,必须自动删除它。如果您愿意并且能够适当地修改ReferenceQueue,则可以使用Observable来避免这种情况。