简体   繁体   中英

What is the purpose of this code in the JDK?

The following code is taken from 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 are

  • Why does the iteration start at listeners.length - 2 what about the listeners.length - 1 element?
  • Why is the event fired for every other element ( i -= 2 )?
  • Why is the iteration going in reverse order?

A link to the code in openjdk as well.

The listeners array contains the listeners' Class objects in the even indices and the listener instances in the odd indices.

Therefore the loop checks the type of each even index in the listeners array

if (listeners[i] == ListDataListener.class

but fires the event only for odd indices :

((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.

As per the code to add a new listener , shown here:

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

the list actually contains pairs of Class instances and object instances.

With regards to the iteration order, perhaps it's a deliberate approach to notifier newer listeners first?

If you look at EventListenerList: the list is built with two elements, one of them is the listener object, the other the class of the object. That explains the 2-by-2 iteration and the check with the other element towards a class.

I find this code pretty ugly, lots of repetitions of this weird iteration loop. I don't have the answer about this rather strane implementation, but IMO the reasons are probably to keep compatibility with the legacy JAVA -keep the APIs the same, and maybe performances, probably with the introduction of generics in java 1.5.

Wy iterate in reverse order? No idea why it's implemented like that. Maybe an implementation decision or an specification that requires to call latest added listeners first. I tried to find another good reason but I couldn't... Moreover it used to iterate in reverse older since at least 1.6 (I did not check with older versions).

The reason they're iterating in reverse order is so they don't have to evaluate .length every time. They're doing it as a performance optimization. Here's a related question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM