我是这些泛型类型的新手。在下面的代码中,我创建了一个接受扩展“字符串”的项目列表的方法。
我的问题?- 当列表可以分配一个新列表时,为什么不能添加字符串“test”......它给了我一个编译错误。
public class Child {
public void takeList(List<? extends String> list){
list = new ArrayList<String>();
list.add("test");
}
}
我是这些泛型类型的新手。在下面的代码中,我创建了一个接受扩展“字符串”的项目列表的方法。
我的问题?- 当列表可以分配一个新列表时,为什么不能添加字符串“test”......它给了我一个编译错误。
public class Child {
public void takeList(List<? extends String> list){
list = new ArrayList<String>();
list.add("test");
}
}
因为它不是这里相关的运行时类型。list仍然是 type List<? extends String>,你只是碰巧将它分配给 a new ArrayList<String>()。考虑一下:
list = rand() ? new ArrayList<String>() : new ArrayList<NotString>();
编译器不可能判断是否list.add("test")有效——它只根据list.
请注意,实际上没有 extends String,它是一个final类。
有细微的差别。它需要一个包含一种事物(扩展字符串的事物)的列表。此列表可能是 String 的子类,因此不是 String iyswim。请参阅http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html上限通配符。
如果它是
public void takeList(List<? *super* String> list){
然后你可以向它添加字符串,因为列表保证能够接受字符串。
当你有一个带有通配符的变量和一个采用泛型类型参数的方法时,Java 无法确保类型安全。它必须禁止这个调用。
考虑一个List<? extends Animal>例子。您可能已经分配了它List<Dog>,但可以为变量分配List<Squid>. 不应允许您将 a 添加Dog到此类列表中。
要允许add调用该方法,请删除通配符。
public void takeList(List<String> list){
此外,String是final,所以说真的没有意义? extends String。