[英]What is the purpose of this code in the JDK?
The following code is taken from Oracle jdk1.8.0_40 AbstractListModel class. 以下代码取自Oracle jdk1.8.0_40 AbstractListModel类。
/**
* <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 我的问题是
listeners.length - 2
what about the listeners.length - 1
element? listeners.length - 2
listeners.length - 1
元素呢? i -= 2
)? i -= 2
)? A link to the code in openjdk as well. 也是openjdk中代码的链接。
The listeners
array contains the listeners' Class
objects in the even indices and the listener instances in the odd indices. listeners
数组包含偶数索引中的侦听器Class
对象和奇数索引中的侦听器实例。
Therefore the loop checks the type of each even index in the listeners
array 因此,循环检查
listeners
数组中每个偶数索引的类型
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. listeners.length - 1
不会被跳过。 Since when i == listeners.length - 2
, i+1 == listeners.length - 1
. 因为当
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. 该列表实际上包含一对
Class
实例和对象实例。
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. 如果查看EventListenerList:列表是使用两个元素构建的,其中一个是侦听器对象,另一个是对象的类。 That explains the 2-by-2 iteration and the check with the other element towards a class.
这解释了2乘2的迭代以及与其他元素对类的检查。
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.
我没有关于这个相当严格的实现的答案,但IMO的原因可能是保持与传统JAVA的兼容性 - 保持API相同,也许是性能,可能是在Java 1.5中引入泛型。
Wy iterate in reverse order? Wy以相反的顺序迭代? 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).
我试图找到另一个很好的理由,但我不能......此外它曾经反向迭代,因为至少1.6(我没有检查旧版本)。
The reason they're iterating in reverse order is so they don't have to evaluate .length
every time. 他们以相反顺序迭代的原因是他们不必每次都评估
.length
。 They're doing it as a performance optimization. 他们将其作为性能优化。 Here's a related question.
这是一个相关的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.