T型不是通用的; 它不能在泛型函数中使用参数<?>错误进行参数化

Sum*_*ain 8 java generics collections

我想创建一个接受任何Map&a String键的泛型函数,如果映射中没有键,那么它应该创建一个Value Type的新实例(传递)并将其放入map中然后把它返还.

这是我的实施

public <T> T getValueFromMap(Map<String, T> map, String key, Class<T> valueClass){
    T value = map.get(key);
    if (value == null){
        try {
            value = valueClass.newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        map.put(key, value);
    }
    return value;
}
Run Code Online (Sandbox Code Playgroud)

如果我使用普通(非通用)List作为值类型,它可以工作

Map<String,List> myMap;
List value = getValueFromMap(myMap, "aKey", List.class) //works
Run Code Online (Sandbox Code Playgroud)

但不是通用类型列表

Map<String,List<String>> myMap;
List<String> value = getValueFromMap(myMap, "aKey", List.class) //does not work
Run Code Online (Sandbox Code Playgroud)

此外,如果我尝试Map<String, T>通过更改它来使map参数泛型,Map<String, T<?>>它抱怨the type T is not generic; it cannot be parameterized with arguments <?>

通用参数本身可以是通用的吗?

有没有办法创建具有上述要求的功能?

〜更新

感谢大家的所有见解.

I have verified that the accepted solution works for any value type with this code

    Map<String, Map<String, List<String>>> outer = 
            new HashMap<String, Map<String,List<String>>>();

    Map<String, List<String>> inner = getValueFromMap(outer, "b", 
            (Class<Map<String, List<String>>>)(Class<?>)HashMap.class);

    List<String> list = getValueFromMap(inner, "a", 
            (Class<List<String>>)(Class<?>)ArrayList.class);
Run Code Online (Sandbox Code Playgroud)

Ami*_*nde 5

您需要最适合您的特定类型String.在您的情况下List.class返回您Class<List<?>>需要特定类型,因此您需要添加强制转换Class<List<String>>

 Map<String,List<String>> myMap = new HashMap<String, List<String>>();;
 List<String> value = getValueFromMap(myMap, "aKey",
           (Class<List<String>>)(Class<?>)ArrayList.class) ;
Run Code Online (Sandbox Code Playgroud)

现在,如果你调用下面的方法

 getValueFromMap(myMap, "aKey",      List.class) 
                ^^^T is List<String>  ^^^ T is List<?> wild char since List.class
                                          will return you Class<List<?>>
Run Code Online (Sandbox Code Playgroud)

因此,您的定义T会导致编译器混淆,因此您将收到编译错误.

你不能创建实例,List.class因为它是接口,你需要它的实现类,所以调用方法ArrayList.class