我可以将 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
来避免这种情况。
我正在修复遗留应用程序,该应用程序存在对象被 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
来避免这种情况。