为什么
List<Map<String, Object>> a, b;
a.addAll(b);
编译
但
List<? extends Map<String, ?>> a, b;
a.addAll(b);
才不是。
如何使后者编译?
为什么
List<Map<String, Object>> a, b;
a.addAll(b);
编译
但
List<? extends Map<String, ?>> a, b;
a.addAll(b);
才不是。
如何使后者编译?
想象一下,CustomHashMap
扩展HashMap
,你初始化a
如下:
List<CustomHashMap<String, String> list = new ArrayList<CustomHashMap<String, String>>();
List<? extends Map<String, ?>> a = list;
如果您能够将条目添加到a
...
a.add(new HashMap<String, String>());
...你会遇到这种奇怪的情况
CustomHashMap<String, String> map = list.get(0); // you would expect to get CustomHashMap object but you will get a HashMap object instead
换句话说,您不知道 Map 的实际类型(当您说 ? extends Map 时),您所知道的只是它是 Map 的某个子类型,并且您不能将任意对象添加到 List,因为您需要确保添加的对象有一个超类型。但是你不能,因为地图的确切类型是未知的。
根据java 文档,您可以在这种情况下声明辅助方法(丑陋但有效):
static <T extends List<K>, V, K extends Map<String, V>> void addAllHelper(T from, T to) {
from.addAll(to);
}
下面的代码应该可以帮助您解释这一点
List<? super Number>
a 称为out
参数,可用于更新
List<? extends Number> b
称为in
参数,可用于读取
由于注释中提到的原因,下面的注释行会导致编译错误
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
List<Double> doubleList = new ArrayList<>();
List<Number> numberList = new ArrayList<>();
addAll(numberList, intList);
addAll(numberList, doubleList);
addAll(intList, doubleList);//cant add double to int
addAll(doubleList,intList);//cant add int double
addAll(intList, numberList);//cant add number to int
}
private static<T> void addAll(List<? super T> a, List<? extends T> b) {
a.addAll(b);
}
当您使用具体的通用类型声明它时,它会编译。如果你定义一个类:
public class AClass<T extends Map<String, ?>> {
public List<T> dostuff() {
List<T> lista = new ArrayList<T>();
List<T> listb = new ArrayList<T>();
lista.addAll(listb);
return lista;
}
}
使用通配符无法编译。
您可以使用以下方法执行此操作:
private <S extends Map<String, ?>> void method(List<S> a, List<S> b){
a.addAll(b);
}