带有通知观察者()的观察者通知顺序



我有以下代码:

public class MyObservable extends Observable {
// ...
public void doSomething() {
// do stuff
setChanged();
notifyObservers();
}
}
public class A implements Observer {
public void update(Observable o, Object arg) {
// do something
}
}
public class B implements Observer {
public void update(Observable o, Object arg) {
// do something
}
}

和主要功能:

public static void main(String[] args) {
MyOvervable a = new MyObservable();
a.addObserver(new A());
a.addOberser(new B());
a.doSomething();
}

调用更新函数的顺序是否与我添加带有addObserver()的观察者的顺序相同notifyObservers()

Javadoc for Observable 说通知是按照侦听器注册的顺序进行的,但这是不正确的 - 通知实际上是以相反的顺序进行的。

带有解释性注释的代码摘录:

// addObserver() adds last-most at end of the list
public synchronized void addObserver(Observer o) {
..
obs.addElement(o);
}
public void notifyObservers(Object arg) {
..
// notifyObservers iterates backwards; last-most first.
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}

我提交了一份错误报告 - https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8214760 - 但是由于Observable被弃用,它已被关闭为"不会修复"。

我的信念是,实现的行为是稳定的,不会改变;更改顺序可能会破坏许多使用它的应用程序的兼容性。

是的。这是javajava.util.Observable类的摘录。

private Vector<Observer> obs;
arrLocal = obs.toArray();
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);

Vector是基于索引的,并由内部的数组备份。Vector保持元素的插入顺序。意味着您可以假设,如果遍历 Vector,您将按照插入的顺序获取对象。

所以你的问题的答案是:

根据 Oracle 的文档:

未指定通知的传递顺序。Observable 类中提供的默认实现将按照观察者注册感兴趣的顺序通知观察者,但子类可以更改此顺序、不使用无保证顺序、在单独的线程上传递通知,或者可以保证其子类按照自己的选择遵循此顺序。

最新更新