Когда использовать EventListenerList вместо общей коллекции слушателей
Когда я узнал, как запускать события на 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 - имеет значение для потока событий?
Ответы
Ответ 1
Для меня главное преимущество EventListenerList
заключается в том, что содержащий класс имеет (или может иметь) более одного типа слушателя. Многие компоненты Swing делают; тот, который вы просматриваете, может и не быть. Второй пример короче, но он имеет неявное ограничение дизайна.
Ответ 2
EventListenerList
имеет метод, getListeners(Class<T> t)
, специально для случая, когда вас интересует только один тип события.
Вот пример того, как его использовать:
protected void fireChangeOccurred(Change change) {
for (ChangeListener listener:
listenerList.getListeners(ChangeListener.class)) {
listener.stateChanged(new ChangeEvent(this));
}
}
Если вы решите сохранить свою собственную коллекцию слушателей, я рекомендую CopyOnWriteArrayList
.
Ответ 3
В наши дни нет огромных преимуществ. Просто небольшие оптимизации. Вот что говорит JavaDocs:
основные преимущества, которые предоставляет этот класс что это относительно дешево в случай без слушателей, и он обеспечивает сериализация списков событий-слушателей в одном месте, а также степень безопасности MT (при правильном использовании)
С современными JVM и коллекциями это действительно не имеет значения. Но то, что вы могли бы сделать с вашей собственной реализацией, - это способ сглаживания изменений на EDT, если вы используете Swing - это было бы полезно.