Reputation: 27425
Consider the following code:
List<? extends Integer> lst= new ArraList<Integer>();
lst.add(5);//Compile error
lst.get(5);//OK
In the second string we have compile error, because we must guaranted have method add(int) in all potencial subtypes of List<? extends Integer>
and compiler know that its null
only, third string returns unknow type and compiler cast him to Object, isnt it?
Upvotes: 0
Views: 108
Reputation: 20726
PECS. Producer extends, Consumer super.
List<? super Integer> lst= new ArrayList<Integer>();
lst.add(5);// No Compile error
The list is a consumer now, you put objects into it...
Also this
lst.get(5);
Is a different cake... You provide the Integer index of which you want to get... (Not to mention what Sotirios mentioned: the return type will be Object
in this case. Also, in this role, the list is a provider...)
Upvotes: 1
Reputation: 280122
You cannot add anything except null
to a List
bounded by a wildcard because you never know the underlying type.
List<? extends Integer> lst= new ArrayList<Integer>();
lst.add(5); // Compile error
lst.get(5); // 5 is just the index
You can however get an element because you know it must be an Integer
(in this case).
It's hard to explain with Integer
because it's a class that cannot be extended. But take this
public class Foo {}
public class Bar extends Foo {}
public class Zoop extends Foo {}
What could you add to
List<? extends Foo> fooList = new ArrayList<Zoop>(); // could come from a method
?
The list is declared as ? extends Foo
even though the runtime object's generic type is Zoop
. The compiler therefore cannot let you add anything. But you are guaranteed to be operating on Foo
objects, so you can retrieve them fine.
Upvotes: 0
Reputation: 178303
Once you have a List<? extends Integer>
, the compiler doesn't know whether it's Integer
or a subtype. The compiler can't ensure the type safety of adding anything except null
(really, passing anything to a method taking a generic type parameter, including the add
method), so it disallows it. This occurs despite the fact that Integer
is final
and no subclasses are allowed.
For the get
method, the compiler knows that the return type is some kind of Integer
, so it allows the call and places an implicit cast to Integer
.
Upvotes: 0