使用反射检索泛型类型信息



假设我有这些类,

public class StringObjectKeyValueStore<V> extends AbstractObjectStore<V>
        implements KeyValueStore<String, V> {
}
public abstract class AbstractObjectStore<V> {
     private final Class<V> type;
     public AbstractObjectStore() {
        this.type = (Class<V>) ((ParameterizedType) getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];
}

我是这样使用的:

KeyValueStore<String,Friend> friendstore = new StringObjectKeyValueStore();

AbstractObjectStore中,如何在不修改AbstractObjectStore构造函数并将Class<V> clazz传递到那里的情况下获得com.xzvf.models.Friend

从我调试这个部分

((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];

仅返回name = {java.lang.String@1452} "V"

你不能。这是不可能的。

首先,Class#getGenericSuperclass()

返回表示实体的直接超类的类型(类、接口、基元类型或void)。

因此,对于StringObjectKeyValueStore,直接超类是AbstractObjectStore,一个ParameterizedType,因为它是用类型变量参数化的。CCD_ 10有一种方法CCD_

返回一个Type对象数组,该数组表示此类型的实际类型参数。

对于您的示例,即StringObjectKeyValueStore,泛型超类是AbstractObjectStore,它在StringObjectKeyValueStore类声明中被赋予了一个单一类型的参数

public class StringObjectKeyValueStore<V> extends AbstractObjectStore<V>

即。类型变量CCD_ 15。因此,对于

KeyValueStore<String,Friend> = new StringObjectKeyValueStore();

这个代码

((ParameterizedType) getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];

将为类型变量CCD_ 17返回一个CCD_。

如果您的申报是

public class StringObjectKeyValueStore<V> extends AbstractObjectStore<String>
                                                                   // ^ see here

然后

((ParameterizedType) getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];

将为String返回Class对象,因为String是您使用的实际类型参数。

唯一可行的方法是将StringObjectKeyValueStore:子类化

class FriendStore extends StringObjectKeyValueStore<Friend>{}

您可以使用TypeTools(我编写的)解析特定类型的V,例如KeyValueStore

Class<?> v = TypeResolver.resolveRawArguments(KeyValueStore.class, FriendStore.class)[1];
assert v == Friend.class;

相关内容

  • 没有找到相关文章

最新更新