1.
Одна возможная проблема при обходе слушателей описана в Swing Hacks item # 94 и возникает, если один из них удаляет себя в качестве слушателя в реализации fooXXX ().
Рассмотрим этот слушатель, который может удалить себя после получения события:
public class FooListener implements EventListener {
private int i;
public FooListener(int i) {
this.i = i;
}
public fooXXX(FooEvent foo) {
System.out.println(i);
if (i == 1) {
((FooEventSource)foo.getSource()).removeListener(this);
}
}
}
и эта реализация обхода слушателя:
public void fireFooXXX() {
for (int i=0; i<listeners.size(); i++) {
// Lazily create the event:
if (fooEvent == null)
fooEvent = new FooEvent(this);
listeners.get(i).fooXXX(fooEvent);
}
}
Теперь предположим, что мы создали ряд таких слушателей:
fooEventSource.addListener(new FooListener(0));
fooEventSource.addListener(new FooListener(1));
fooEventSource.addListener(new FooListener(2));
fooEventSource.addListener(new FooListener(3));
Запуск события даст следующий результат:
0
1
3
Мы бы зациклились на слушателях по индексу, от 0 до 3. При индексе 1 слушатель удаляет себя из внутреннего массива слушателей, в результате чего слушатели 2 и 3 смещаются вниз к индексу 1 и 2. Цикл продолжается с индексом 2, который теперь содержит прослушиватель 3. Прослушиватель 2 был пропущен.
Путем итерации в обратном направлении эта проблема устраняется, поскольку удаление слушателя только сместит индекс прослушивателей, которые уже были вызваны.
Но
EventListenerList не имеет этой проблемы, поскольку методы add () и remove () являются копируемыми при записи, а обход слушателя в предлагаемом использовании работает с экземпляром списка слушателей, возвращаемым getListenerList () перед циклом.
Еще несколько обсуждений об этом можно найти в этой теме , где причины, по-видимому, сводятся к одной из:
2
akf и Michael Borgwardt уже ответили, что EvenListenerList хранит типы слушателей в дополнение к слушателям. Я предполагаю, что причина этого в том, что он позволяет одному EventListenerList обрабатывать прослушиватели разных типов.