-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
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.
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.