为什么
List<Map<String, Object>> a, b;
a.addAll(b);
编译
但是
List<? extends Map<String, ?>> a, b;
a.addAll(b);
没有。
如何让后者编译?
答案 0 :(得分:2)
您无法将项添加到通配符通用列表中。第一个编译因为它有一个已定义的类型。
然而,您可能会找到一些适合您目的的超类,并将其用作通用参数。
<强>更新强>
答案 1 :(得分:2)
想象一下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中,因为您需要确保添加的对象有一个超类型。但你不能,因为地图的确切类型是未知的。
答案 2 :(得分:1)
根据java docs你可以在这种情况下声明帮助方法(丑陋但有效):
static <T extends List<K>, V, K extends Map<String, V>> void addAllHelper(T from, T to) {
from.addAll(to);
}
答案 3 :(得分:0)
当您使用具体的Generic Type声明它时,它会编译。如果您定义一个类:
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;
}
}
使用通配符无法编译。
答案 4 :(得分:0)
您可以使用以下方法执行此操作:
private <S extends Map<String, ?>> void method(List<S> a, List<S> b){
a.addAll(b);
}
答案 5 :(得分:0)
下面的代码可以帮助您解释这个
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);
}