We have made in a tutorial an example with the following signture (as part of an interface)
<T> List<Comparable<T>> sort(Collection<Comparable<T>> c, boolean ascending);
We have found it nearly impossible to implement that method without warnings:
public <T> List<Comparable<T>> sort(Collection<Comparable<T>> c, boolean ascending) {
List<T> list = new ArrayList<T>();
Collections.sort(list);
return list;
}
The error in the line Collections.sort(list) we get is:
Bound mismatch: The generic method sort(List<T>) of type Collections is not
applicable for the arguments (List<T>). The inferred type T is not a valid
substitute for the bounded parameter <T extends Comparable<? super T>>
However, it works for the following signature:
<T extends Comparable<T>> List<T> sort(Collection<T> c, boolean ascending);
With that signature, the code above (implementation of sort) just works as expected. I would like to know what is the reason for that.
Collections.sortexpects aList<T extends Comparable<? super T>>, i.e. the compiler needs to be able to tell that the element typeTof the list it is sorting extendsComparable<E>whereEisT, a superclass ofTor an interface implemented byT. Your first signature withpublic <T> List<Comparable<T>> sortdoesn’t enforce this, so you can’tCollections.sortaList<T>. You could make it work by sayingto match the type that your sort method returns, but the problem with this is that it’s rather inflexible – it can only sort a
Collection<Comparable<Foo>>, not aCollection<Bar>whereBar implements Comparable<Foo>. The most flexible approach would be to stick with thenew ArrayList<T>()but use a signature likewhich places the minimum restriction on
Tto make the sort valid – it would work withBar extends Foo implements Comparable<Foo>, which your second signature doesn’t allow (that would requireBar implements Comparable<Bar>).