fredoverflow
fredoverflow

Reputation: 263220

generic methods and wildcards

What are the differences 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 what extends and super mean in Generics. My question is whether there is a difference between foo, bar and baz. Should I make one of the parameters invariant and the other one variant in the appropriate direction, or should I make both of them variant? Does it make a difference?

Upvotes: 3

Views: 353

Answers (3)

meriton
meriton

Reputation: 70574

The only difference is whether T represents the type parameter of the List, the Comparator, or something in between.

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

For the method implementation foo is probably most convenient, as it allows modifying the list without needing an additional capture conversion, which would require delegating to a helper method.

Upvotes: 2

Puppy
Puppy

Reputation: 146968

I believe that ? extends T means that the List may be generic of any type that is derived from T, whereas List<T> can only be a List of T and not any of its derived classes.

Upvotes: 1

Bozho
Bozho

Reputation: 597234

PECS - Producer extends, consumer super.

To explain this "rule":

  • extends means the genericized object produces elements of the type. When it's a collection, it means you can only take elements from the collection, but not put them in. The comparator
  • super means the object consumes objects of the selected type. So you can add to the collection, but not read from it.
  • the lack of extends and super means you can do both for the exact type specified.

Regarding the Comparator, I don't think it makes any difference. Normally, it would be <? super T> because you the comparator consumes objects, but in all three cases you can safely invoke Collections.sort(list, comparator); (the signature of which is <? super T>)

Upvotes: 5

Related Questions