简体   繁体   English

带有通配符的Java泛型类型

[英]Java generic type with wildcard

I want to write a method that can accept the parameter: 我想写一个可以接受参数的方法:

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

So, here is what I coded: 所以,这是我编码的:

/**
 * 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;
}

And the EMPTY_LIST is defined as below: EMPTY_LIST的定义如下:

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

The problem is that when I call this method with following code, Eclipse tells me a error that the given parameter's type is not applicable. 问题是当我用下面的代码调用这个方法时,Eclipse告诉我一个错误,即给定参数的类型不适用。

getListValueFromMap(cityNameMap, "key");

And the error is: 错误是:

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

Where am I going wrong with this? 我哪里错了?

Here is the definition of cityNameMap : 这是cityNameMap的定义:

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

It's important to take note of what ? extends Object 注意什么是很重要的? extends Object ? extends Object actually represents in generics. ? extends Object实际上代表泛型。

In its current incantation, it is an upper-bounded wildcard which has its upper bound as Object . 在它当前的咒语中,它是一个上限通配符 ,其上限为Object Ideally, this would imply that you could use any list from it, but since generics are invariant, that wouldn't be the case here at all - you could only use lists which have the same bound. 理想情况下,这意味着您可以使用其中的任何列表,但由于泛型是不变的,根本不是这种情况 - 您只能使用具有相同边界的列表。

Since the containing type of the list may change from map to map, set your bound on a generic type to get at the list you care about instead. 由于列表的包含类型可能会从映射更改为映射,因此请在泛型类型上设置绑定以获取您关注的列表。

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;
}

Be sure to update your EMPTY_LIST dependency accordingly; 请务必相应地更新您的EMPTY_LIST依赖项; obviously in this state, you can't return the list bounded with Object . 显然在这种状态下,你不能返回与Object绑定的列表。

This has the advantage of allowing you to pass your list in with any supplied type, and you won't be able to simply add elements to it once you retrieve them from your map due to the way the generic argument is done on the list. 这样做的好处是允许您使用任何提供的类型传递列表,并且由于在列表上完成泛型参数的方式,一旦从映射中检索元素,您将无法简单地向其添加元素。

You could do this: 你可以这样做:

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

Both don't give me any issues in my IDE (IntelliJ 2016.1.1), but it could be that yours has different settings. 两者都没有在我的IDE(IntelliJ 2016.1.1)中给我任何问题,但可能是你的设置不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM