Common Methods and Wildcards

What is the difference between the following three signatures?

static <T> void foo(List<T>,           Comparator<? super T>);
static <T> void bar(List<? extends T>, Comparator<T>        );
static <T> void baz(List<? extends T>, Comparator<? super T>);


I know the meaning of extends

and super

in Generics. My question is if there is a difference between foo

, bar

and baz

. Should I make one of the parameters invariant and the other in the appropriate direction, or should I do both? Does it matter?


source to share

3 answers

The only difference is whether the T

parameter is a type List

, Comparator

or something in between.

As far as the caller is concerned, the three method signatures are equivalent, that is, whenever one of them can be used, the others can also be used.

The method foo

is probably the most convenient to implement , as it allows the list to be modified without the need for additional capture conversion, which would require delegation to the helper method.



PECS - Producer Extends, Consumer Super.

To explain this rule:

  • extends

    means that the generated object creates elements of this type. When it is a collection, it means that you can only take items from the collection, but not insert them. Comparator
  • super

    means that the object consumes objects of the selected type. This way, you can add to the collection, but not read it.
  • The lack of extensions and super means you can do and the exact type that is specified.

As for Comparator

, I don't think it matters. This will usually be <? super T>

because the comparator uses objects, but in all three cases, you can safely call Collections.sort(list, comparator);

(whose signature <? super T>




I believe that ? extends T

means it List

can be generic to any type that is derived from T, whereas there List<T>

can only be List

of T

and not any of its derived classes.



All Articles