Java nested generic type mismatch
在下面的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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)第二呼叫到呼叫的工作,但不到四(一)吗?
我得到以下错误:
1 | The method fourth(List<List<?>>) in the type `TestTest` is not applicable for the arguments (`List<List<String>>`) |
如果您想用>
1 2 3 | private static void fourth(List<? extends List<?>> a){ System.out.println("List of a List of anything"); } |
号
因为与>
>
1 2 3 4 5 6 7 8 9 | 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 |
理由很简单。如果你有
1 2 3 4 |
。
然后,如果您可以这样调用该方法:
1 2 3 | List<List<String>> a = new ArrayList<List<String>>(); fourth(a); String fail = a.get(0).get(0); // ClassCastException here! |
一个>
>
你应该能够把任何>
>
This implies that the type is unknown and objects of any type can be added to
List that are>
heterogeneous and compiler cannot guarantee that all object inList are of same type. Hence it cannot be passed to new>
ArrayList that takes a bounded type as parameter.>()
号
>
>
但
1 2 3 |
1 2 3 4 5 | List<List<?>> == List { //That contains any unknown type lists List<Integer>, List<String>, List<Object> } |
。
其中as
1 2 3 4 5 | List<? extends List<?> == List { //That contains same unknown type lists List<Integer>, List<Integer>, List<Integer> } |
。
所以这里
1 2 3 4 5 | List<List<String>> == List { //That contains same String lists List<String>, List<String>, List<String> } |
因此,>
所以调用
1 2 3 4 | List<List<?>> a1 = new ArrayList<List<?>>(); a1.add(new ArrayList<String>()); a1.add(new ArrayList<Integer>()); a1.add(new ArrayList<Object>()); |
。