使用notifyObservers()的观察者通知顺序

时间:2017-07-12 09:29:27

标签: java observer-pattern

我有以下代码:

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

notifyObservers()调用更新函数的顺序与我添加addObserver()观察者的顺序相同吗?

3 个答案:

答案 0 :(得分:1)

是的。这是java java.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保持element的插入顺序。意味着您可以假定,如果在Vector上进行迭代,则将按照插入顺序获得对象。

因此,您的问题的答案是:

答案 1 :(得分:1)

根据Oracle的docs

  

未指定发送通知的顺序。 Observable类中提供的默认实现将以观察者注册兴趣的顺序通知观察者,但是子类可以更改此顺序,不使用保证的顺序,在单独的线程上传递通知,或可以保证其子类遵循此顺序,因为它们选择。

答案 2 :(得分:1)

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,因此已将其关闭,因为“无法修复”。

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