Java集合中addAll(..)方法的正确参数类型是什么?如果我做这样的事情:
List<? extends Map<String, Object[]>> currentList = new ArrayList<Map<String, Object[]>>();
Collection<HashMap<String, Object[]>> addAll = new ArrayList<HashMap<String, Object[]>>();
// add some hashmaps to the list..
currentList.addAll(addAll);
我知道我需要初始化这两个变量。但是,我得到了一个编译错误(来自eclipse):
Multiple markers at this line
- The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments (List<capture#2-of ? extends
Map<String,Object[]>>)
- The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments
(Collection<HashMap<String,Object[]>>)
我做错了什么?
答案 0 :(得分:8)
将extends
替换为super
。
addAll()
本身会收到? extends T
个参数,当T
为? extends Map<K, V>
时,该参数无效。随着变化,它将变得有效? extends ? super Map<K, V>
。
但更好的方法是删除? extends
(或? super
)。在这种特殊情况下,它是多余的。只需使用List<Map<String, Object[]>>
即可。 addAll()
将有效地采用? extends Map<String, Object[]>>
。
答案 1 :(得分:7)
您只能将T
的实例插入List<T>
。
类型List<? extends Map<X,Y>>
代表未知类型T
的列表extends Map<X,Y>
。例如,它可以代表List<LinkedHashMap<X,Y>>
。显然,您可能不会在这样的列表中插入普通的HashMap<X,Y>
。
你可能想要:
List<Map<String, Object[]>> currentList;
或者如果你想要变得非常灵活,你可以这样做:
List<? super Map<String, Object[]>> currentList;
这会让你做一些疯狂的事情:
currentList = new ArrayList<Map<? super String, ? extends Object[]>>();
您可能还希望阅读Angelika Langer的Generics常见问题解答,尤其是the section about wildcards。
答案 2 :(得分:6)
请记住:
对于<? extends ...>
,你不能把东西(除了null)放进去
对于<? super ...>
,你不能从中得到东西(除了对象)
答案 3 :(得分:1)
您无法在此类列表上调用任何具有通用属性的方法。基本上,? extends Foo
所说的是“扩展Foo
”的东西,但你不知道那是什么。返回该类型时,您可以说返回的值为Foo
或某个子类型。但是对于任何给定的值,你不能匹配? extends Foo
generic。
简而言之:您需要更改currentList
声明或将其转换为List
(不带泛型)并发出警告或(如果你知道你在做什么的话就压制它。
答案 4 :(得分:0)
你的问题基本归结为:
public static <T extends Collection<?>> void foo(T t) {
T x = null;
x.addAll(t);
}
这将失败,基本上与您描述的错误相同。尝试沿着这些方向修改它。
public static <T extends Collection<Y>, Y> void foo(T t) {
T x = null;
x.addAll(t);
}
或者,在上面的示例中,您可以更改
List<? extends Map<String, Object[]>> currentList;
到
List<Map<String, Object[]>> currentList;
如果你尝试开始传递未指定的类型,泛型会很快变得毛茸茸。