0

我的应用程序正在抛出

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

我想要实现的是在运行时获取K和的类名:V

这样做:

Map<String,String> dsMap = DS.getMap(mapName);

我将获取andjava.lang.String的类名,或者获取任何参数化的类名(不实例化and )kClazzvClazzClass<K>Class<V>

我的代码可能有什么问题?

4

3 回答 3

1

参数化类型表示泛型类型的具体实现。您可以像考虑模板文档之间的关系一样考虑泛型和参数化类型之间的关系。模板告诉您将在哪里填写信息,文档包含实际填写的信息。在您的示例中:

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

两者都是泛型类型(DsMapMap模板)。它们的实际泛型参数不是由类本身指定的,因此编译器不会捕获它们。换句话说,它们的通用信息在运行时不可用。

为了在运行时捕获实际的泛型参数,这些参数需要成为类签名的一部分。例如,您的类的这个简单扩展将起作用:

public class DsMapIntegerString extends DsMap<Integer, String>

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

于 2013-04-02T18:13:36.120 回答
0

DsMap实现了一个泛型接口 ( Map<K,V>),但它没有扩展一个泛型类。所以getClass().getGenericSuperclass()返回一个对 的引用java.lang.Object,它不能被强制转换为ParameterizedType

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

例如:

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

...

public class StringIntDsMap extends DsMap<String, Integer> {

...

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

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

于 2013-04-02T18:10:48.217 回答
0

目视检查说尝试改变:

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

static public class DsMap<K, V> extends HashMap<K, V> {
于 2013-04-02T18:17:30.893 回答