为什么我无法添加到List <! - ?在Java中扩展String - >?

时间:2015-08-29 06:04:27

标签: java generics arraylist

在下面的代码段中,添加&#34; Hulooo&#34;列表生成编译器错误,因为String不扩展String。 但是,类型化字符串的ArrayList工作。但是对对象的ArrayList进行类型转换并不起作用。

有人可以解释为什么会这样吗? 什么适用于String(在此上下文中)不适用于Object?

public static void takeList(List<? extends String> list)
{
    list.add("Hulloo");//ERROR
    list=new ArrayList<String>();
    list=new ArrayList<Object>();//ERROR
}

1 个答案:

答案 0 :(得分:4)

问号?是一个所谓的外卡操作员。 List<? extends String>表示:任何类型List<T> TString或子类型为StringString是一个最终类,因此没有String的子类型,但编译器不会看这个。因此,编译器假定列表可能是String的某个子类型的列表,并且不可能将String添加到这样的列表中。

让我们使用非最终类A来模拟您的示例,该类具有子类B

class A { 
    // empty
}

class B extends A {
    void f();
}

现在考虑相当于你的方法:

public static void takeList(List<? extends A> list) {
    list.add(new A());
}

由于以下原因,这将无法编译。假设您按如下方式调用此方法:

List<B> myList = new ArrayList<>();   // line 1
takeList(myList);                     // line 2
B element = myList.get(0);            // line 3
B.f();                                // line 4

由于BA的子类,因此第2行中的函数调用是合法的。但是方法takeList会将A添加到列表中,而不是B。然后,B的列表包含一个不是B的元素,第3行和第4行分解。

类型系统用于防止输入错误,因此如果有一种情况可以将错误类型的对象添加到列表中,则类型系统必须禁止它。