Java 在运行时获取泛型类型类名

Java 在运行时获取泛型类型类名,java,reflection,Java,Reflection,我的申请书在投递 java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 对于此代码: public class DsMap<K,V> implements Map<K, V>{ protected Class<K> kClazz; protected Class<V> vClazz;

我的申请书在投递

java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
对于此代码:

public class DsMap<K,V> implements Map<K, V>{
    protected Class<K> kClazz;
    protected Class<V> vClazz;  

    // Called during DS.getMap(mapName) method
    public DsMap(String name) {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        Type typeK = genericSuperclass.getActualTypeArguments()[0];
        Type typeV = genericSuperclass.getActualTypeArguments()[1];

        if (typeK instanceof Class) {
            this.kClazz = (Class<K>) typeK;
        } else if (typeK instanceof ParameterizedType) {
            this.kClazz = (Class<K>) ((ParameterizedType)typeK).getRawType();
        }

        if (typeV instanceof Class) {
            this.vClazz = (Class<V>) typeV;
        } else if (typeV instanceof ParameterizedType) {
            this.vClazz = (Class<V>) ((ParameterizedType)typeV).getRawType();
        }           
    }
}
我将为
kClazz
vClazz
的类名获取
java.lang.String
,或者获取参数化的任何类名(不实例化
class
class


我的代码中可能有什么错误?

DsMap
实现了一个通用接口(
Map
),但它不扩展通用类。因此
getClass().getGenericSuperclass()
返回对
java.lang.Object
的引用,该引用不能转换为
ParameterizedType

(ParameterizedType)getClass().getGenericSuperclass()技巧仅在以下情况下适用
1) 子类扩展了泛型类
2) 子类在编译时声明其类型参数

e、 g:

公共抽象类DsMap实现映射{

公共类StringIntDsMap扩展了DsMap{

然后,
getGenericSuperclass()
将返回
DsMap
,可以将其转换为
ParameterizedType
,并且从
getActualTypeArguments()
返回的
Type[]
数组中的条目可以转换为
Class


不幸的是,这不是一个非常普遍的情况。我经常使用它在单元测试之间共享代码(我可以在编译时声明泛型类型)。但它不能推广到运行时之前类型不可用的情况。

参数化类型表示泛型类型的具体实现。您可以像思考模板和文档之间的关系一样思考泛型类型和参数化类型之间的关系。模板告诉您在何处使用如果要填写信息,文档中实际填写的信息。在您的示例中:

public class DsMap<K,V> implements Map<K, V>

因为您提供了具体的参数,所以由
getClass().getGenericSuperclass()
返回的类型实际上将是一个参数化的类,并且您的代码将不再失败。

目视检查显示尝试更改:

static public class DsMap<K, V> implements Map<K, V> {
静态公共类DsMap实现映射{

静态公共类DsMap扩展了HashMap{

要使此方法起作用,您必须将
DsMap
抽象并用实类型实例化,例如
new DsMap(){}
。您可能会发现查看的文档和实现非常有用。
public class StringIntDsMap extends DsMap<String, Integer> {
public class DsMap<K,V> implements Map<K, V>
public class DsMapIntegerString extends DsMap<Integer, String>
static public class DsMap<K, V> implements Map<K, V> {
static public class DsMap<K, V> extends HashMap<K, V> {