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
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.
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.
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
.