类型T不是通用的;不能使用参数<?>对其进行参数化泛型函数中的错误 [英] The type T is not generic; it cannot be parameterized with arguments <?> error in a generic function

查看:41
本文介绍了类型T不是通用的;不能使用参数<?>对其进行参数化泛型函数中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个通用函数,该函数可以接受任何Map&字符串键,如果该键不存在于映射中,则它应创建一个新的值类型实例(已传递).把它放在地图上然后将其退回.

I want to create a generic function that takes any Map & a String key, if the key is not present in the map, then it should create a new instance of the Value Type (which is passed) & put it in the map & then return it.

这是我的实现方式

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

如果我将其与普通(非通用)列表作为值类型一起使用,它将起作用

It works if I use it with a normal (not generic) List as the value type,

Map<String,List> myMap;
List value = getValueFromMap(myMap, "aKey", List.class) //works

但没有通用类型列表

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

另外,如果我尝试通过将 Map< String,T> 映射参数更改为 Map< String,T<?> 来使映射参数通用,则会抱怨类型T不是通用的;不能使用参数<?>

Also if I try to make Map<String, T> map parameter generic by changing it to Map<String, T<?>> it complains that the type T is not generic; it cannot be parameterized with arguments <?>

可以将通用参数本身设为通用吗?

Can the generic parameters be themselves made generic?

有什么方法可以创建具有上述要求的功能?

Is there any way to create function with above mentioned requirements?

〜更新

感谢大家的深刻见解.

我已经验证了接受的解决方案适用于使用此代码的任何值类型

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

推荐答案

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

You need most specific types which is String in your case. List.class returns you Class<List<?>> in your case you need specific type so you will need to add cast 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) ;

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

Now if you invoke method like below

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

因此您对 T 的定义正在引起编译器的混乱,因此您会遇到编译错误.

So your defination of T is causing confusion to Compiler so you are getting compile error.

您不能创建 List.class 的实例,因为它是接口,您将需要其实现类,因此请使用 ArrayList.class

You can not create instance of List.class since it is interface you will need implemention class of it so call method with ArrayList.class

这篇关于类型T不是通用的;不能使用参数&lt;?&gt;对其进行参数化泛型函数中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆