Reputation: 53806
The below code causes a compile time error :
The method add(capture#1-of ? extends Object) in the type List is not applicable for the arguments (String)
code :
List<? extends Object> a1 = new ArrayList();
a1.add("string");
Error is at line :
a1.add("string");
Since class String extends from Object why ref a1 not accept a String type ?
Upvotes: 4
Views: 235
Reputation: 124215
List<? extends Object>
can be used with every type of lists.
How do you think, would it be safe to let it add any objects if for example
List<? extends Object> a1 = new ArrayList<Integer>();
a1.add("string");
Only safe value to add would be null
since it doesn't belong to any specific type.
To get rid of this problem you can use for example List<String> a1 = new ArrayList<String>()
or List a1 = new ArrayList()
Upvotes: 1
Reputation: 5883
I recommend reading this article, http://java.dzone.com/articles/covariance-and-contravariance. (Italic additions are mine)
In summary, we use covariance
<? extends Object>
when we only intend to take generic values out of a structure. We use contravariance<? super Object>
when we only intend to put generic values into a structure and we use an invariant<Object>
when we intend to do both.
You defined your list as holding a covariant Object type, which means you can write Object o = a1.get(1)
but you can't write a1.add("foo")
. If you want to be able to add Objects but not get them back, then you would need to define your list like this:
List<? super Object> a1 = new ArrayList<>();
It's a bit unfortunate, in my opinion, language authors used the terms extend
and super
to indicate covariance and contravariance, especially in the above example since there is no super type of Object
.
Upvotes: 4
Reputation: 4492
? extends Object
means "some unknown type X
that extends Object
". By trying to add a String
to the collection, you're essentially claiming X = String
, which the compiler cannot verify. As far as the compiler knows, X
could just as well be Integer
or something completely different.
In other words List<? extends Object>
does NOT mean "anything that extends Object
goes". A simple List<Object>
means that.
Upvotes: 4