Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我能把WeakReference传递给可观察的听众吗?_Java_Observer Pattern_Weak References - Fatal编程技术网

Java 我能把WeakReference传递给可观察的听众吗?

Java 我能把WeakReference传递给可观察的听众吗?,java,observer-pattern,weak-references,Java,Observer Pattern,Weak References,我正在修复一个遗留应用程序,该应用程序在实现Observable的类中的观察者列表保留对象时存在问题。正确地移除观察者将是一项漫长的任务,因此我认为我可以使用WeakReference来克服这一问题。问题是,调用Observable.addObserver(newweakreference(something))是不可能的,因为WeakReference没有实现Observable。所以我想创建一个名为WeakObserver的类,如下所示: public class WeakObserver&

我正在修复一个遗留应用程序,该应用程序在实现Observable的类中的观察者列表保留对象时存在问题。正确地移除观察者将是一项漫长的任务,因此我认为我可以使用
WeakReference
来克服这一问题。问题是,调用
Observable.addObserver(newweakreference(something))
是不可能的,因为
WeakReference
没有实现Observable。所以我想创建一个名为
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);
}
}
公共类WeakObserver扩展WeakReference实现Observer{
私人T观察员;
公共安全观察者(最终观察者){
超级观察员;
this.observer=观察者;
}
@凌驾
公共无效更新(可观察o,对象arg){
更新(o,arg);
}
}
这里的问题很明显-除了不安全的强制转换
update
方法之外,我正在创建另一个对我想要垃圾回收的对象的引用

像这样的事情可能发生吗,或者我是在试图做一些愚蠢的事情吗?

(以我的评论为基础)与其保留引用,不如依赖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);
        }
    }


}
私有类Observer弱扩展WeakReference实现Observer{
公共观察者弱(观察者引用){
超级(参照物);
}
@凌驾
公共无效更新(可观测obs、对象参数){
if(super.get()!=null){
super.get().update(obs,arg);
}
}
}

您可能可以做到这一点,但您希望您的弱可观测对象对真实的
可观测对象具有弱引用,而不是弱引用

此外,这还不足以让真正的观察家受到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实现了Observer{
私人最终参考观察员;
私人最终观察到的;
公共武器观察者(观察者,可观察者){
this.observer=新的WeakReference(observer);
这是观察到的;
}
@凌驾
公共无效更新(可观察o,对象arg){
Observer realObserver=Observer.get();
if(realObserver!=null){
realObserver.update(o,arg);
}否则{
观察。删除观察者(本);
}
}
}

WeakObserver
特定于单个
可观察的
,这是在底层真实
观察者
为GC'd时自动删除它所必需的。如果您愿意并且能够适当地修改可观察的对象,您可以使用
引用队列来避免这种情况。

因此,您希望允许对
观察者
对象进行GC'd,问题是它们被登记在
可观察的
列表中?是的,完全正确。我能想到的唯一一件事是重新实现
Observable
方法来使用
WeakReference
objects WeakObserver是否需要实例变量observer?为什么不在update方法中依赖WeakReference的get()方法-检查是否为null,如果不为null,则将调用委托给非null引用?我没有想到这一点。我试试看,thx.人们还在使用观察者界面吗?我不是说观察者模式,只是Java接口。这可能是我正在寻找的解决方案。我仍然无法让GC清除这些观察者,但它们可能在其他地方被引用,所以我必须深入研究堆转储。