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 elementlisteners.length - 1
? - Why
i -= 2
does the event fire for every other element ( )? - Why is iteration going in reverse?
Link to code in openjdk .
source to share
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.
source to share
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?
source to share
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).
source to share
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.
source to share