Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8090609

Prohibitively restrictive invariance in ListChangeListener.Change

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • None
    • javafx

      This is a snippet of ListChangeListener.Change API:

          public abstract static class Change<E> {
              public Change(ObservableList<E> list);
          
              public ObservableList<E> getList();
              public List<E> getAddedSubList();
              public abstract List<E> getRemoved();
          }

      Note the invariance of the type argument E.

      Combine this with the fact that the client never gets Change<E> from ObservableList<E>, but only Change<? extends E>, due to the ListChangeListener.onChanged signature:

          public interface ListChangeListener<E> {
              public void onChanged(Change<? extends E> c);
          }

      This makes a type-safe implementation of a method that takes two subsequent list changes (of the same ObservableList) and merges them into one list change impossible:

          Change<E> merge(Change<? extends E> c1, Change<? extends E> c2) {
              // no way to implement this
          }

      (Changing the return type to Change<? extends E> does not help.)

      Being able to accumulate subsequent list changes into a single change is very useful. It is implemented in ReactFX, but only using unsafe casts.

      What would help, is to change the quoted part of the Change API to

          public abstract static class Change<E> {
              public Change(ObservableList<? extends E> list);
          
              public ObservableList<? extends E> getList();
              public List<? extends E> getAddedSubList();
              public abstract List<? extends E> getRemoved();
          }

      That is, change <E> to <? extends E> in both the constructor and return types of methods returning lists.

      I believe this is a non-breaking change, since, as mentioned above, the client is already able to get only Change<? extends E> (not Change<E>), so she only gets [Observable]List<? extends E> from the above methods anyway.

            nlisker Nir Lisker
            tmikula Tomas Mikula
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Imported: