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
将其分配给变量,它也会失败。
我有以下通用接口和一个实现 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<IntegerData>
或者List<DataInterface<Integer>>
是不兼容List<DataInterface<?>>
的,因为我也可以给后者加一个DataInterface<String>
。解决方案是使用 extends:
private static void doSomething(List<? extends DataInterface<?>> dataList)
这将阻止向列表中添加任何内容(null
除外),因此可以安全使用。
通过包装列表,泛型类型因类型推断而改变。如果您使用 var
将其分配给变量,它也会失败。