我有一个 HashMap,其中的值是 ArrayList,我正在尝试编写一个函数来接受这些 HashMap 的通用实例
HashMap<String, ArrayList<Integer>> myMap = new HashMap<String, ArrayList<Integer>>();
public static void foo(HashMap<?, ArrayList<?>> a) {}
public static void bar(HashMap<?, ? extends ArrayList<?>> a) {}
// Compilation Failure!
foo(myMap);
// This works, but why do I need ? extends ArrayList
bar(myMap)
错误信息是
The method
foo(HashMap<?,ArrayList<?>>)
in the typeExample
is not applicable for the arguments (HashMap<String,ArrayList<Integer>>
).
为什么我需要为扩展 ArrayList 使用通配符?
我认为通过 ArrayList<?>
(没有 ? extends
),我可以将函数限制为仅具有 ArrayList 值的 HashMap。
我也知道以下通用方法有效:
public static <K,V> void printer(HashMap<K, ArrayList<V>> list) { }
这和我想的一样ArrayList<?>
会工作。有人可以解释这里的微妙之处吗?
最佳答案
通配符语法是故意设计来(误)引导人们相信它匹配任何类型。这适用于简单的情况
List<?> <= List<String> // OK, right is subtype of left
但请记住,它只适用于第一层,而不是更深的
List<List<?> <= List<List<String>> // FAIL
这很好
List<? extends List<?>> <= List<List<String>>
因为新的一级 ?
.
如果S
是 T
的子类型, G<S>
是 G<? extends T>
的子类型.适用于 S=List<String>
的情况, T=List<?>
.
关于带有 ArrayList 通配符的 Java HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6603146/