Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics <? super> wildcard

I was wondering why the following bit of code does not work:

Collection <? super String> col = new ArrayList<String>();
col.add(new Object());// does not compile
col.add("yo!");// compiles indeed;

If the type is <? super String> it can contain anything which is super of String (String included) not?

like image 770
Rollerball Avatar asked Jul 02 '13 07:07

Rollerball


People also ask

What is <? Super T in Java?

super T denotes an unknown type that is a supertype of T (or T itself; remember that the supertype relation is reflexive). It is the dual of the bounded wildcards we've been using, where we use ? extends T to denote an unknown type that is a subtype of T .

What is the difference between List <? Extends T and List <? Super T >?

super is a lower bound, and extends is an upper bound.

What is a generic wildcard?

The question mark (?) is known as the wildcard in generic programming. It represents an unknown type. The wildcard can be used in a variety of situations such as the type of a parameter, field, or local variable; sometimes as a return type.

What is difference between extends and super?

Producer – If you want to only retrieve the elements from a generic collection, use extends . Consumer – If you want to only put elements into a generic collection, use super . If you do both retrieve and put operations with the same collection, you shouldn't use either extends or super .


2 Answers

Collection<? super String>, counter to your intuition, does not mean "a collection which contains objects of type String or its supertype". It means "col will be a collection holding some definite type, which itself is String or its supertype" (such as Object, Serializable, or CharSequence).

The best way to think about Collection<? super String> is that it is not a type, like you are used to in Java, but a pattern against which specific types are matched.

Now, the only thing you can safely add to any collection which matches the above pattern is a String or its subclass (if there were any). Quite the opposite of what you would have expected, isn't it? That's Generics for you.

like image 155
Marko Topolnik Avatar answered Oct 11 '22 12:10

Marko Topolnik


With a Collection <? super String>, we don't know what kind of objects it contains exactly, but we know that it must be a collection of either String or some superclass of String, i.e. it is safe to put a String into it but not necessarily an Object. Conversely for methods that take things out of the collection (e.g. when iterating) we can't be sure we'll get strings back.

On the other hand with Collection<? extends Foo> we know it's a collection of something that is either Foo or some subclass of Foo, so we can safely take something from the collection and know it will be assignable to Foo, but we can't put anything in because we have no way of knowing what types would be safe.

like image 31
Ian Roberts Avatar answered Oct 11 '22 11:10

Ian Roberts