Когда я изучил, как запустить события в Java, я познакомился с EventListenerList. Когда я создаю своих собственных слушателей, я пишу слушателю, таким образом, это расширяет EventListener, я храню их в EventListenerList, и мой метод огня прошел бы слушателей события как это:
protected void fireChangeOccurred(Change change) {
Object[] listeners = listenerList.getListenerList();
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ChangeListener.class) {
((ChangeListener)listeners[i+1]).changeOccurred(change);
}
}
}
Теперь я рассматриваю код, который просто помещает слушателей в HashMap (мог быть любой набор), интерфейс слушателя не расширяет EventListener, и метод огня похож на это:
protected void fireChangeOccurred(Change change) {
for (ChangeListener listener : listeners) {
listener.changeOccurred(change);
}
}
Каковы преимущества использования EventListenerList вместо того, чтобы просто вести мой собственный список слушателей? Действительно только имеет значение, если слушатели находятся в компоненте Swing - это имеет значение для Потока Отправки События?
На мой взгляд, главное преимущество EventListenerList
заключается в том, что содержащий класс имеет (или может иметь) более одного типа слушателя. Многие компоненты Swing делают это; тот, который вы рассматриваете, может и не иметь. Второй пример короче, но в нем есть это неявное ограничение на проектирование.
EventListenerList
имеет метод, getListeners(Class
, специально для случая, когда вас интересует только один тип события.
Вот пример его использования:
protected void fireChangeOccurred(Change change) {
for (ChangeListener listener:
listenerList.getListeners(ChangeListener.class)) {
listener.stateChanged(new ChangeEvent(this));
}
}
Если вы решили вести свою собственную коллекцию слушателей, я рекомендую CopyOnWriteArrayList
.
В наши дни огромных преимуществ нет. Просто небольшие оптимизации. Вот что говорит JavaDocs:
основные преимущества, которые предоставляет этот класс в том, что это относительно дешево в случай отсутствия слушателей, и он обеспечивает сериализация для списков слушателей событий в одном месте, а также степень безопасности MT (при правильном использовании)
С современными JVM и коллекциями это действительно не имеет значения. Но что вы могли бы сделать со своей собственной реализацией, так это предоставить способ запускать изменения в EDT, если вы используете Swing - это было бы полезно.