2015-07-29 2 views
3

Следующий код взят из класса Oracle jdk1.8.0_40 AbstractListModel.Какова цель этого кода в JDK?

/** 
    * <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); 
      } 
     } 
    } 

Мои вопросы

  • Почему начало итерации в listeners.length - 2 чем о listeners.length - 1 элемента?
  • Почему событие срабатывает для каждого другого элемента (i -= 2)?
  • Почему итерация идет в обратном порядке?

Ссылка на code in openjdk также.

+0

Посмотрите на 'addListDataListener', чтобы понять, почему он реализован так. Также обратите внимание, что слушатели вызывают в обратном порядке их дополнение к модели. – KDM

+0

Я полагаю, что вопрос о 'listeners.length - 2' и' i - = 2' связан. Я не могу проверить код прямо сейчас, но немедленное объяснение, о котором я могу думать, состоит в том, что, возможно, два элемента добавляются в 'listenerList' каждый раз, когда прослушиватель зарегистрирован, и только один из них должен быть уведомлен. – Chop

+2

Javadoc и исходный код 'javax.swing.event.EventListenerList' предоставляют исчерпывающую документацию о том, почему экземпляр этого класса используется таким образом. –

ответ

6

массив listeners содержит объекты прослушивания Class в четных индексах и экземплярах слушателя в нечетных индексах.

Поэтому цикл проверяет тип каждого четного индекса в массиве listeners

if (listeners[i] == ListDataListener.class 

, но запускает событие только для нечетных индексов:

((ListDataListener)listeners[i+1]).contentsChanged(e); 

listeners.length - 1 не пропускается. С тех пор, когда i == listeners.length - 2, i+1 == listeners.length - 1.

Я не уверен в причине итерации обратного порядка.

+0

Обратный порядок - это то, что модель запускает события в обратном порядке их добавления. – KDM

+3

@ KDM Вопрос в том, почему модель делает это. – Eran

+0

Он должен. Если он не выполняет итерацию в обратном порядке, первый добавленный прослушиватель запускается первым, и это может быть не то, что требуется. Все события, совершаемые в Swing, делают то же самое. – KDM

1

В соответствии с кодом на add a new listener, как показано здесь:

public void addListDataListener(ListDataListener l) { 
    listenerList.add(ListDataListener.class, l); 
} 

список фактически содержит пары Class экземпляров и экземпляры объектов.

Что касается итерационного порядка, возможно, это преднамеренный подход, чтобы сначала уведомить новых слушателей?

1

Если вы посмотрите на EventListenerList: список построен с двумя элементами, один из которых является объектом-слушателем, а другой - классом объекта. Это объясняет итерацию 2 на 2 и проверку с другим элементом по отношению к классу.

Я нахожу этот код довольно уродливым, много повторений этого странного цикла итерации. У меня нет ответа об этой довольно строгой реализации, но ИМО причины, вероятно, должны поддерживать совместимость с унаследованным JAVA -пробовать API-интерфейсы одинаково, а может быть, и исполнения, возможно, с введением дженериков в java 1.5.

Wy итерации в обратном порядке? Не знаю, почему это реализовано так. Может быть, решение о внедрении или спецификация, требующая сначала вызвать последних добавленных слушателей. Я попытался найти еще одну вескую причину, но я не мог ... Кроме того, она использовалась для повторения в обратном порядке старше, так как по крайней мере 1,6 (я не проверял более старые версии).

1

Причина, по которой они повторяются в обратном порядке, так что им не нужно оценивать .length каждый раз. Они делают это как оптимизацию производительности.Here's a related question.

Смежные вопросы