observable.java

来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 209 行

JAVA
209
字号
/*
 * @(#)Observable.java	1.19 97/02/18
 *
 * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of Sun
 * Microsystems, Inc. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Sun.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
 * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
 * THIS SOFTWARE OR ITS DERIVATIVES.
 *
 * CopyrightVersion 1.1_beta
 *
 */

package java.util;

/**
 * This class represents an observable object, or "data"
 * in the model-view paradigm. It can be subclassed to represent an
 * object that the application wants to have observed.
 * <p>
 * An observable object can have one or more observers. After an
 * observable instance changes, an application calling the
 * <code>Observable</code>'s <code>notifyObservers</code> method
 * causes all of its observers to be notified of the change by a call
 * to their <code>update</code> method.
 *
 * @author  Chris Warth
 * @version 1.19, 02/18/97
 * @see     java.util.Observable#notifyObservers()
 * @see     java.util.Observable#notifyObservers(java.lang.Object)
 * @see     java.util.Observer
 * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
 * @since   JDK1.0
 */
public class Observable {
    private boolean changed = false;
    private Vector obs;
    /* a temporary array buffer, used as a snapshot of the state of
     * current Observers.  We do notifications on this snapshot while
     * not under synchronization.
     *
     * Removed to fix IBM defect 9386                                      IBM 9386
     * Temporary array made an instance variable in 'notifyObservers'      IBM 9386
     * to fix a memory leak                                                IBM 9386
     * This fix is very similar to that employed by Sun in JDK1.2          IBM 9386                                                            IBM
     */
    //private Observer[] arr = new Observer[2];                         /* IBM 9386 */
    /** Construct an Observable with zero Observers */

    public Observable() {
	obs = new Vector();
    }

    /**
     * Adds an observer to the set of observers for this object.
     *
     * @param   o   an observer to be added.
     * @since   JDK1.0
     */
    public synchronized void addObserver(Observer o) {
	if (!obs.contains(o)) {
	    obs.addElement(o);
	}
    }

    /**
     * Deletes an observer from the set of observers of this object.
     *
     * @param   o   the observer to be deleted.
     * @since   JDK1.0
     */
    public synchronized void deleteObserver(Observer o) {
	    obs.removeElement(o);
    }

    /**
     * If this object has changed, as indicated by the
     * <code>hasChanged</code> method, then notify all of its observers
     * and then call the <code>clearChanged</code> method to
     * indicate that this object has no longer changed.
     * <p>
     * Each observer has its <code>update</code> method called with two
     * arguments: this observable object and <code>null</code>.
     *
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#hasChanged()
     * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
     * @since   JDK1.0
     */
    public void notifyObservers() {
	notifyObservers(null);
    }

    /**
     * If this object has changed, as indicated by the
     * <code>hasChanged</code> method, then notify all of its observers
     * and then call the <code>clearChanged</code> method to indicate
     * that this object has no longer changed.
     * <p>
     * Each observer has its <code>update</code> method called with two
     * arguments: this observable object and the <code>arg</code> argument.
     *
     * @param   arg   any object.
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#hasChanged()
     * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
     * @since   JDK1.0
     */
    public void notifyObservers(Object arg) {

	int size=0;
        Observer [] arr;                                                /* IBM 9386 */

	synchronized (this) {
	    /* We don't want the Observer doing callbacks into
	     * into arbitrary code while holding its own Monitor.
	     * The code where we extract each Observable from
	     * the Vector 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;
	    size = obs.size();
	    //if (size > arr.length) {                                  /* IBM 9386 */
		arr = new Observer[size];
	    //}                                                         /* IBM 9386 */
	    obs.copyInto(arr);
	    clearChanged();
	}

	for (int i = size -1; i>=0; i--) {
	    if (arr[i] != null) {
		arr[i].update(this, arg);
	    }
	}
    }

    /**
     * Clears the observer list so that this object no longer has any observers.
     *
     * @since   JDK1.0
     */
    public synchronized void deleteObservers() {
	obs.removeAllElements();
    }

    /**
     * Indicates that this object has changed.
     *
     * @since   JDK1.0
     */
    protected synchronized void setChanged() {
	changed = true;
    }

    /**
     * Indicates that this object has no longer changed, or that it has
     * already notified all of its observers of its most recent change.
     * This method is called automatically by the
     * <code>notifyObservers</code> methods.
     *
     * @see     java.util.Observable#notifyObservers()
     * @see     java.util.Observable#notifyObservers(java.lang.Object)
     * @since   JDK1.0
     */
    protected synchronized void clearChanged() {
	changed = false;
    }

    /**
     * Tests if this object has changed.
     *
     * @return  <code>true</code> if the <code>setChanged</code> method
     *          has been called more recently than the <code>clearChanged</code>
     *          method on this object; <code>false</code> otherwise.
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#setChanged()
     * @since   JDK1.0
     */
    public synchronized boolean hasChanged() {
	return changed;
    }

    /**
     * Returns the number of observers of this object.
     *
     * @return  the number of observers of this object.
     * @since   JDK1.0
     */
    public synchronized int countObservers() {
	return obs.size();
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?