通用扩展不能添加相同的类型

时间:2013-10-10 00:29:52

标签: java

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

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

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

3 个答案:

答案 0 :(得分:1)

因为这不是与此相关的运行时类型。 list仍为List<? extends String>类型,您恰好将其分配给new ArrayList<String>()。考虑一下:

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

编译器无法判断list.add("test")是否有效 - 它只根据list的编译时类型做出决定。

请注意,实际上没有任何内容扩展String,而是final类。

答案 1 :(得分:0)

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

如果是

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

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

答案 2 :(得分:0)

当您拥有带通配符的变量和带有泛型类型参数的方法时,Java无法确保类型安全。它必须禁止这个电话。

例如考虑List<? extends Animal>。您可能已为其分配了List<Dog>,但可以为变量分配List<Squid>。不应该允许您将Dog添加到此类列表中。

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

public void takeList(List<String> list){

此外,String is final,所以没有必要说? extends String