嵌套列表中的通用类型和通配符

Generic types and wildcards in nested lists

我正在尝试编写一个方法,将任何列表的列表作为参数 - 无论嵌套列表的类型如何。
对于采用任何类型的单个列表的方法,通配符类型工作正常(参见示例 1)。但是这个概念并没有扩展到列表的列表。从示例 2 中可以看出,该方法仅接受 List<List<?>> 类型的参数,但不接受 List<List<Integer>> 等特定类型的参数。示例 3 使用类型参数 T 并接受 List<List<Integer>> 但不再接受 List<List<?>>。为什么会这样,我如何编写一个同时接受 List<List<?>>List<List<Integer>> 的方法?

public void test()
{
    List<Integer> list1;
    List<?> list2;
    
    example1(list1); // Valid
    example1(list2); // Valid
    
    List<List<Integer>> listOfLists1;
    List<List<?>> listOfLists2;
    
    example2(listOfLists1); // Error
    example2(listOfLists2); // Valid
    
    example3(listOfLists1); // Valid
    example3(listOfLists2); // Error
}

public void example1(List<?> list) {}

public void example2(List<List<?>> listOfLists) {}

public <T> void example3(List<List<T>> listOfLists) {}

对我有用:

List<List<Integer>> listOfLists1;
List<List<?>> listOfLists2;

public TestKlasse() {
    init();
}

public void init(){
    listOfLists1 = new ArrayList();
    listOfLists2 = new ArrayList();
    listOfLists1.add(Arrays.asList(1,2,3,4,5));
    listOfLists2.add(Arrays.asList("a","a",2,4,"5"));
    test((Collection)listOfLists1);
    test((Collection)listOfLists2);
}

private void test(Collection<Collection<?>> list){
    list.forEach(e -> {
        System.out.println(e.toString());
    });
}

结果:

[1, 2, 3, 4, 5]
[a, a, 2, 4, 5]

希望这个解决方案符合您的期望。

example2 不起作用,因为 List<List<Integer>> 不是 List<List<?>> 的子类型,即使 List<Integer>List<?> 的子类型,类似于List<String> 不是 List<Object> 的子类型,尽管 StringObject 的子类型。基本上,当类型没有被通配符直接参数化时,类型参数必须完全匹配——List<Integer>List<?> 不完全匹配。 (里面有一个通配符,但它是具体类型的一部分List<?>,而不是顶层的通配符。)

为了能够接受不同类型的参数,它需要在顶层有一个通配符:

public void example4(List<? extends List<?>> listOfLists) {}