在以下示例中:
public static void main(String[] args) {
List<String> b = new ArrayList<String>();
first(b);
second(b);
List<List<String>> a = new ArrayList<List<String>>();
third(a);
fourth(a); // doesnt work
}
private static <T> void first(List<T> a){
System.out.println("List of T");
}
private static void second(List<?> a){
System.out.println("List of anything ");
}
private static <T> void third(List<List<T>> a){
System.out.println("List of a List of T ");
}
private static void fourth(List<List<?>> a){
System.out.println("List of a List of anything ");
}
为什么第二个(b)的呼叫有效,但第四个(a)的呼叫不?
我收到以下错误:
The method fourth(List<List<?>>) in the type `TestTest` is not applicable for the arguments (`List<List<String>>`)
答案 0 :(得分:14)
如果您希望能够使用fourth
参数调用List<List<String>>
,那么您需要将签名更改为:
private static void fourth(List<? extends List<?>> a){
System.out.println("List of a List of anything ");
}
上述方法有效,因为与List<List<?>>
不同,List<? extends List<?>>
与List<List<String>>
兼容。想一想:
List<List<String>> original = null;
List<? extends List<?>> ok = original; // This works
List<?> ok2 = original; // So does this
List<List<?>> notOk = original; // This doesn't
List<Integer> original = null;
List<? extends Number> ok = original; // This works
List<?> ok2 = original; // So does this
List<Number> notOk = original; // This doesn't
推理很简单。如果你有
private static void fourth(List<List<?>> a) {
List<?> ohOh = Arrays.asList(new Object());
a.add(ohOh);
}
然后,如果你可以调用该方法:
List<List<String>> a = new ArrayList<List<String>>();
fourth(a);
String fail = a.get(0).get(0); // ClassCastException here!
答案 1 :(得分:5)
List<List<String>>
不是List<List<?>>
。
无论List<?>
是什么,您都应该能够将List<List<?>>
放入?
。 List<List<String>>
只接受List<String>
。
答案 2 :(得分:2)
这意味着类型是未知的,任何类型的对象都可以添加到
List<List<?>>
heterogeneous
,并且编译器不能保证List<List<?>>
中的所有对象都是相同的类型。因此,它无法传递给以有界类型为参数的新ArrayList<List<String>>()
。
答案 3 :(得分:1)
List<List<String>>
与List<List<?>>
不同。泛型在本质上是不变的。如果您只执行List<?>
并通过List<String>
,那么它将起作用,因为List of Anything
可以由Lists of String
表示。
但List of List of anything
无法代表List of List of String
。
@Lukas Elder
已经指定了可行的案例。这是第二个可行的案例
private static void fourth(List<?> a){
System.out.println("List of anything ");
}
答案 4 :(得分:0)
List<List<?>> == List { //That contains any unknown type lists
List<Integer>,
List<String>,
List<Object>
}
在哪里
List<? extends List<?> == List { //That contains same unknown type lists
List<Integer>,
List<Integer>,
List<Integer>
}
所以这里
List<List<String>> == List { //That contains same String lists
List<String>,
List<String>,
List<String>
}
因此List<? extends List<?>
是List<List<String>>
的超级类型且可分配。
调用fourth
方法的有效值如下所示。
List<List<?>> a1 = new ArrayList<List<?>>();
a1.add(new ArrayList<String>());
a1.add(new ArrayList<Integer>());
a1.add(new ArrayList<Object>());