从超类型类中获取泛型参数

时间:2012-03-29 22:58:20

标签: java reflection

假设我有一个像这样的父接口/类

interface Parent<T> {}

和许多修复泛型类型的实现接口。

interface Child extends Parent<Type> {}

如果我有Class T对象,我可以使用反射来获取代表Class的{​​{1}}实例。像这样:

Child

目前我将<T, I extends Parent<T>> I create(Class<I> type) { Class<T> tType = ... ... } 作为参数传入,但如果可以,我想简化一些事情。

3 个答案:

答案 0 :(得分:6)

是的,尽管其他人已经说过,但如果您有权访问子类“Class”对象,则此信息 可用。您需要将getGenericSuperclassgetActualTypeArguments一起使用。

ParameterizedType superClass = (ParameterizedType)childClass.getGenericSuperclass();
System.out.println(superClass.getActualTypeArguments()[0]);

在您的示例中,“actual”类型参数应返回Class的{​​{1}}。

答案 1 :(得分:1)

如果您需要在运行时使用泛型类型执行任何非常重要的操作,请考虑Guava的TypeToken。它可以回答你的问题(以及更多!),同时解决评论者提出的一些细微问题:

private interface Parent<T> {}
private interface Intermediate<U, V> extends Parent<V> {}
private interface Child<Z> extends Comparable<Double>, Intermediate<Z, Iterable<String>> {}

public void exploreGuavaTypeTokens() {
    final TypeToken<? super Child> token = TypeToken.of(Child.class).getSupertype(Parent.class);
    final TypeToken<?> resolved = token.resolveType(Parent.class.getTypeParameters()[0]);
    System.out.println(resolved); // "java.lang.Iterable<java.lang.String>"
    final Class<?> raw = resolved.getRawType();
    System.out.println(raw); // "interface java.lang.Iterable"
}

答案 2 :(得分:-3)

我不这么认为。阅读type erasure:泛型类型仅用于编译时检查,然后丢弃。它们不存储在已编译的类文件中,因此它们在运行时不可用。