带有通配符的Java泛型类型

时间:2016-04-13 06:48:54

标签: java generics

我想编写一个可以接受参数的方法:

Map<String, [the type here could be anything]>

所以,这就是我编码的内容:

/**
 * Get list value from a map, empty list if there's no key matched 
 */
private List<? extends Object> getListValueFromMap(Map<String, List<? extends Object>> map, String key) {
    List<? extends Object> list = map.get(key);
    return list == null ? EMPTY_LIST : list;
}

EMPTY_LIST的定义如下:

List<Object> EMPTY_LIST = Collections.unmodifiableList(new ArrayList<Object>());

问题在于,当我使用以下代码调用此方法时,Eclipse会告诉我一个错误,即给定参数的类型不适用。

getListValueFromMap(cityNameMap, "key");

错误是:

  

The method getListValueFromMap(Map<String,List<? extends Object>>, String) in the type ChinaAreaResource is not applicable for the arguments (Map<String,List<City>>, String)

我在哪里错了?

以下是cityNameMap的定义:

/** map city's name to city list */
private Map<String, List<City>> cityNameMap;

2 个答案:

答案 0 :(得分:4)

注意? extends Object在泛型中实际代表的内容非常重要。

在目前的咒语中,它是upper-bounded wildcard,其上限为Object。理想情况下,这将暗示你可以使用它中的任何列表,但由于泛型是不变的,根本不是这里的情况 - 你只能使用具有相同约束的列表

由于列表的包含类型可能会从地图更改为地图,因此请在通用类型上设置绑定以获取您关注的列表。

private <T> List<? extends T> getListValueFromMap(Map<String, List<T>> map, String key) {
    List<? extends T> list = map.get(key);
    return list == null ? EMPTY_LIST : list;
}

请务必相应地更新您的EMPTY_LIST依赖关系;很明显,在这种状态下,您无法返回与Object绑定的列表。

这样做的好处是允许您使用任何提供的类型传递列表,并且一旦从地图中检索到它们,您就无法简单地向其中添加元素通用参数在列表中的完成方式。

答案 1 :(得分:0)

你可以这样做:

private <T> List<T> getListValueFromMap(Map<String, List<T>> map, String key) {
    //
}

两者都没有在我的IDE(IntelliJ 2016.1.1)中给我任何问题,但可能是你的设置不同。