Kev*_*vin 4 java generics wildcard arraylist hashmap
我有一个HashMap,其值是ArrayLists,我正在尝试编写一个函数来接受这些HashMaps的泛型实例
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)
Run Code Online (Sandbox Code Playgroud)
错误消息是
foo(HashMap<?,ArrayList<?>>)类型中的方法Example不适用于arguments(HashMap<String,ArrayList<Integer>>).
为什么我需要为extends ArrayList使用通配符?
我认为通过拥有ArrayList<?>(没有? extends),我可以将函数限制为仅具有ArrayList值的HashMaps.
我也知道以下通用方法有效:
public static <K,V> void printer(HashMap<K, ArrayList<V>> list) { }
Run Code Online (Sandbox Code Playgroud)
这表现我的想法ArrayList<?>会起作用.有人能解释这里的细微之处吗?
通配符语法是故意设计的(错误)引导人们相信它匹配任何类型.这适用于简单的情况
List<?> <= List<String> // OK, right is subtype of left
Run Code Online (Sandbox Code Playgroud)
但请记住,它只适用于第一级,而不是更深
List<List<?> <= List<List<String>> // FAIL
Run Code Online (Sandbox Code Playgroud)
这可以
List<? extends List<?>> <= List<List<String>>
Run Code Online (Sandbox Code Playgroud)
因为新的第1级?.如果S是子类型T,G<S>则是子类型G<? extends T>.适用于,S=List<String>以及T=List<?>.