27

我最近阅读了 Java 的Observable类。我不明白的是:在通知观察者(notifyObservers())之前,我必须调用 setChanged()。notifyObservers 方法中有一个布尔值,需要我们调用 setChanged。布尔值的用途是什么,为什么我必须调用 setChanged()?

4

5 回答 5

29

在长时间的处理中,您可能会调用多次setChanged()但最后只调用一次notifyObservers()。如果在结束之前,由于内部原因您决定回滚,您可以选择调用clearChanged()。在后一种情况下,notifyObservers()无效。

于 2013-02-27T19:56:43.363 回答
3

setChanged()

将此 Observable 对象标记为已更改;hasChanged 方法现在将返回 true。

notifyObservers()

如果该对象发生了变化,如 hasChanged 方法所示,则通知其所有观察者,然后调用 clearChanged 方法以指示该对象不再更改。

基本上你setChanged()用来通知观察者超类发生了变化。然后你调用这个notifyObservers()方法来告诉观察者发生了什么变化。

那里的 setChanged() 因为它允许类在通过调用通知观察者之前撤消更改clearChanged()。如果您没有 setChanged() 标志,那么您实际上是在通知观察者并且没有检测到任何更改,因此他们不会响应“通知”。

请参阅我的代码以获取更多说明:

主要方法公共类 SpeedRunner {

public static void main(String[] args) {
    SpeedMonitor monitor = new SpeedMonitor();
    // Create a speedometer and register the monitor to it...
    SpedoMeter speedo = new SpedoMeter();
    speedo.addObserver(monitor);
    // Drive at different speeds...
    speedo.setCurrentSpeed(50);
    speedo.setCurrentSpeed(70);
    speedo.setCurrentSpeed(40);
    speedo.setCurrentSpeed(100);
    speedo.setCurrentSpeed(69);
}

观察者(当有趣的事情发生时被通知的对象):

//this is the observer since it is observing changes in the speedo.
public class SpeedMonitor implements Observer {
public static final int SPEED_TO_ALERT = 70;

public void update(Observable obs, Object obj) {
    SpedoMeter speedo = (SpedoMeter) obs;
    if (speedo.getCurrentSpeed() > SPEED_TO_ALERT) {
        System.out.println("** ALERT ** Driving too fast! (" + speedo.getCurrentSpeed() + ")");
    } else {
        System.out.println("... nice and steady ... (" + 
        speedo.getCurrentSpeed() + ")");
        }
    }
}

主题(感兴趣的对象)

public class SpedoMeter extends Observable{
private int currentSpeed;

public SpedoMeter(){
    currentSpeed = 0;
}

public void setCurrentSpeed(int speed){
    currentSpeed = speed;

//        setChanged();
    notifyObservers();
}

        public int getCurrentSpeed() {
        return currentSpeed;
    }

}

注释掉 setChanged() ,你会注意到观察者没有拾取任何东西,因此控制台是空的。

看这本教科书。学习设计模式真的很好。

贝维斯,托尼。Java 设计模式要点(Kindle 位置 1835)。能力第一限制。Kindle版。

于 2018-04-09T20:17:37.717 回答
1

setchanged() 用作更改状态的指示或标志。如果为 true,则 notifyObservers() 可以运行并更新所有观察者。如果为 false,则在不调用 setchanged() 的情况下调用 notifyObservers(),并且不会通知观察者。

于 2014-10-24T13:53:19.327 回答
1

可能的原因可能是 setChanged() 具有受保护的修饰符。同时,notifyObservers() 可以在任何地方调用,甚至可以由观察者调用。从那以后,observable 和observer 可以通过这种机制相互交互。

于 2015-05-21T12:48:17.827 回答
0
public void notifyObservers(Object arg) {
    /*
     * a temporary array buffer, used as a snapshot of the state of
     * current Observers.
     */
    Observer[] arrLocal;

    synchronized (this) {
        /* We don't want the Observer doing callbacks into
         * arbitrary Observables while holding its own Monitor.
         * The code where we extract each Observable from
         * the ArrayList and store the state of the Observer
         * needs synchronization, but notifying observers
         * does not (should not).  The worst result of any
         * potential race-condition here is that:
         *
         * 1) a newly-added Observer will miss a
         *   notification in progress
         * 2) a recently unregistered Observer will be
         *   wrongly notified when it doesn't care
         */
        if (!hasChanged())
            return;

        arrLocal = observers.toArray(new Observer[observers.size()]);
        clearChanged();
    }

    for (int i = arrLocal.length-1; i>=0; i--)
        arrLocal[i].update(this, arg);
}

评论是原因

于 2017-12-29T03:46:12.087 回答