What is the purpose of this code in the JDK?

The following code is taken from the Oracle jdk1.8.0_40 AbstractListModel class.

   /**
     * <code>AbstractListModel</code> subclasses must call this method
     * <b>after</b>
     * one or more elements of the list change.  The changed elements
     * are specified by the closed interval index0, index1 -- the endpoints
     * are included.  Note that
     * index0 need not be less than or equal to index1.
     *
     * @param source the <code>ListModel</code> that changed, typically "this"
     * @param index0 one end of the new interval
     * @param index1 the other end of the new interval
     * @see EventListenerList
     * @see DefaultListModel
     */
    protected void fireContentsChanged(Object source, int index0, int index1)
    {
        Object[] listeners = listenerList.getListenerList();
        ListDataEvent e = null;

        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == ListDataListener.class) {
                if (e == null) {
                    e = new ListDataEvent(source, ListDataEvent.CONTENTS_CHANGED, index0, index1);
                }
                ((ListDataListener)listeners[i+1]).contentsChanged(e);
            }
        }
    }

      

My questions

  • Why does iteration start with listeners.length - 2

    what about an element listeners.length - 1

    ?
  • Why i -= 2

    does the event fire for every other element ( )?
  • Why is iteration going in reverse?

Link to code in openjdk .

+3


source to share


4 answers


The array listeners

contains Class

listener objects at even indices and listener instances at odd indices.

So the loop checks the type of every even index in the array listeners

if (listeners[i] == ListDataListener.class

      

but fires an event for odd indexes only:



((ListDataListener)listeners[i+1]).contentsChanged(e);

      

listeners.length - 1

is not skipped. Since when i == listeners.length - 2

, i+1 == listeners.length - 1

.

I'm not sure about the reason for the reverse order iteration.

+6


source


According to the code, add a new listener shown here:

public void addListDataListener(ListDataListener l) {
    listenerList.add(ListDataListener.class, l);
}

      



the list actually contains pairs of instances Class

and instances of objects.

In terms of iterative order, perhaps this is a deliberate approach to notify new listeners first?

+1


source


If you look at the EventListenerList: the list is built with two elements, one of which is the listener object and the other is the object class. This explains the 2-by-2 iteration and checking with a different element relative to the class.

I find this code quite ugly, a lot of repetition of this weird loop of iteration. I don't have an answer about this rather strict implementation, but IMO seems to be able to maintain compatibility with legacy JAVA -programming APIs the same, and maybe executions, perhaps with the introduction of generics in java 1.5.

Please try in reverse order? I don’t know why it is implemented like this Maybe an implementation decision, or a specification requiring the last added listeners to be called first. I tried to find another good reason, but I couldn't ... Also, it was used to repeat in reverse order of the older since at least 1.6 (I haven't checked older versions).

+1


source


The reason they are repeated in reverse order is because they don't have to evaluate every time .length

. They do it as a performance optimization. Here is a related question.

+1


source







All Articles