1

我是这些泛型类型的新手。在下面的代码中,我创建了一个接受扩展“字符串”的项目列表的方法。

我的问题?- 当列表可以分配一个新列表时,为什么不能添加字符串“test”......它给了我一个编译错误。

public class Child {
    public void takeList(List<? extends String> list){
        list = new ArrayList<String>();
        list.add("test");
    }
}
4

3 回答 3

1

因为它不是这里相关的运行时类型。list仍然是 type List<? extends String>,你只是碰巧将它分配给 a new ArrayList<String>()。考虑一下:

list = rand() ? new ArrayList<String>() : new ArrayList<NotString>();

编译器不可能判断是否list.add("test")有效——它只根据list.

请注意,实际上没有 extends String,它是一个final类。

于 2013-10-10T00:33:19.800 回答
0

有细微的差别。它需要一个包含一种事物(扩展字符串的事物)的列表。此列表可能是 String 的子类,因此不是 String iyswim。请参阅http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html上限通配符。

如果它是

     public void takeList(List<? *super* String> list){

然后你可以向它添加字符串,因为列表保证能够接受字符串。

于 2013-10-10T00:34:29.600 回答
0

当你有一个带有通配符的变量和一个采用泛型类型参数的方法时,Java 无法确保类型安全。它必须禁止这个调用。

考虑一个List<? extends Animal>例子。您可能已经分配了它List<Dog>,但可以为变量分配List<Squid>. 不应允许您将 a 添加Dog到此类列表中。

要允许add调用该方法,请删除通配符。

public void takeList(List<String> list){

此外,Stringfinal,所以说真的没有意义? extends String

于 2013-10-10T00:35:33.553 回答