我最近阅读了 Java 的Observable类。我不明白的是:在通知观察者(notifyObservers())之前,我必须调用 setChanged()。notifyObservers 方法中有一个布尔值,需要我们调用 setChanged。布尔值的用途是什么,为什么我必须调用 setChanged()?
5 回答
在长时间的处理中,您可能会调用多次setChanged()但最后只调用一次notifyObservers()。如果在结束之前,由于内部原因您决定回滚,您可以选择调用clearChanged()。在后一种情况下,notifyObservers()无效。
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版。
setchanged() 用作更改状态的指示或标志。如果为 true,则 notifyObservers() 可以运行并更新所有观察者。如果为 false,则在不调用 setchanged() 的情况下调用 notifyObservers(),并且不会通知观察者。
可能的原因可能是 setChanged() 具有受保护的修饰符。同时,notifyObservers() 可以在任何地方调用,甚至可以由观察者调用。从那以后,observable 和observer 可以通过这种机制相互交互。
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);
}
评论是原因