Java 以通用项作为参数的通用列表

Java generic List with genric items as parameter

我有以下通用接口和一个实现 class:

public interface DataInterface<T> {
    T getData();
    void printData();
}
public class IntegerData implements DataInterface<Integer> {

    private Integer value;
    
    public IntegerData(Integer value) {
        this.value = value;
    }

    @Override
    public Integer getData() {
        return null;
    }

    @Override
    public void printData() {
        System.out.println(this.value);        
    }

}

这里我的代码使用了 class:

public class Main {

    public static void main(String[] args) {
        List<IntegerData> dataList = new ArrayList<>();
        dataList.add(new IntegerData(1));
        
        doSomething(dataList); <-- Compiler error
        
        //this work
        doSomething(Collections.unmodifiableList(dataList));
        doSomething(new ArrayList<>(dataList));
    }
    
    private static void doSomething(List<DataInterface<?>> dataList) {
        for (DataInterface<?> data : dataList)
            data.printData();
    }
}

如果我尝试调用 List 类型的 doSomething 方法,编译器会提示“Main 类型的方法 doSomething(List>) 不适用于参数 (List)”。

但是如果我包装我的特定列表或创建一个新列表,那么它就可以工作。我想知道为什么直接调用不起作用。这是什么原因?

一个List<IntegerData>或者List<DataInterface<Integer>>是不兼容List<DataInterface<?>>的,因为我也可以给后者加一个DataInterface<String>。解决方案是使用 extends:

private static void doSomething(List<? extends DataInterface<?>> dataList)

这将阻止向列表中添加任何内容(null 除外),因此可以安全使用。

通过包装列表,泛型类型因类型推断而改变。如果您使用 var 将其分配给变量,它也会失败。