2013-10-10 34 views
1

我是新来的这些泛型类型。在下面的代码中,我创建了一个接受扩展“String”的项目列表的方法。通用扩展不能添加相同类型

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

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

回答

1

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

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

编译器不可能知道是否list.add("test")将是有效的 - 它才有基础上list编译时类型决定。

请注意,实际上没有任何扩展String,这是一个final类。

0

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

如果是

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

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

0

当你有一个带有通配符的变量和一个采用泛型类型参数的方法时,Java不能确保类型安全。它必须禁止此呼叫。例如,可以考虑List<? extends Animal>。您可能已经为其分配了List<Dog>,但该变量可以分配为List<Squid>。您不应该被允许将Dog添加到这样的列表中。要调用add方法,请删除通配符。

public void takeList(List<String> list){ 

此外,String is final,所以真的是没有一点说? extends String