Reputation: 20856
I'm new to these generic types. In the below code, I created a method that accepts a List of items that extends "String".
My Question? - When the list can be assigned with a new list that is , why can't a string "test" can be added...It gives me a compilation error.
public class Child {
public void takeList(List<? extends String> list){
list = new ArrayList<String>();
list.add("test");
}
}
Upvotes: 1
Views: 63
Reputation: 178253
When you have a variable with a wildcard, and a method that takes the generic type parameter, Java cannot ensure type safety. It must disallow this call.
Consider a List<? extends Animal>
for example. You may have assigned it List<Dog>
, but the variable could be assigned a List<Squid>
. You shouldn't be allowed to add a Dog
to such a list.
To allow the add
method to be called, remove the wildcard.
public void takeList(List<String> list){
Besides, String
is final
, so there really is no point to saying ? extends String
.
Upvotes: 0
Reputation: 2712
There's a subtle difference. It takes a list that contains one type of thing (a thing that extends string). This list may be a subclass of String and therefore not be a String iyswim. See http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html Upper bounded wildcards.
If it was
public void takeList(List<? *super* String> list){
Then you could add strings to it, because the list is guaranteed to be able to accept Strings.
Upvotes: 0
Reputation: 129497
Because it's not the runtime type that's relevant here. list
is still of type List<? extends String>
, you've just happened to assign it to a new ArrayList<String>()
. Consider this:
list = rand() ? new ArrayList<String>() : new ArrayList<NotString>();
The compiler could not possibly tell if list.add("test")
will be valid -- it only makes decisions based on the compile-time type of list
.
Note that in reality nothing extends String
, it's a final
class.
Upvotes: 1