Java反射:获取具体类型的已实现通用接口

时间:2011-10-21 03:21:08

标签: java generics reflection

假设我有一个类似下面的课程

public class AtomEntryHandler implements ConsumingHandler<AtomEntry>
{
...
}

是否可以从AtomEntryHandler.class的类对象获取类对象AtomEntry.class?

我认为由于擦除不可能,但朋友说它是。

4 个答案:

答案 0 :(得分:8)

您可以获取接口和直接子类的泛型类型,但仅适用于具体实现。例如,如果您有一个List<T>实例,则由于类型擦除,您无法知道它被参数化的内容。如果类定义包含在编译时已知的参数化类型(例如,class StringList extends List<String>),那么可以检索该信息。

ParameterizedType pt = (ParameterizedType)AtomEntryHandler.class.getGenericInterfaces()[0];
Class atomEntryClass = (Class)pt.getActualTypeArguments()[0];

答案 1 :(得分:4)

在接口实现的情况下,我无法找到确定基本类型参​​数的方法(这并不意味着没有)。但这与它的接近程度非常接近。

import java.lang.reflect.*;
public class Foo {
  static class Bar<T> {
  }
  static class SubBar extends Bar<Integer> {
  }

  public static void main(String argv[]) {
    ParameterizedType pt = (ParameterizedType)SubBar.class.getGenericSuperclass();
    Type[] t = pt.getActualTypeArguments();
    for (int i=0;i<t.length;i++) {
       System.out.println(t[i]);
    }
  }
}

结果: class java.lang.Integer

答案 2 :(得分:1)

如果您碰巧知道ConsumingHandlerAtomEntryHandler实现的唯一接口,并且您碰巧知道它只需要一个类型参数,那么您可以这样做:

interface ConsumingHandler<T> {}

class AtomEntry {}

class AtomEntryHandler implements ConsumingHandler<AtomEntry>
{
    public static void main( String[] args )
    {
        Type[] interfaces = AtomEntryHandler.class.getGenericInterfaces();
        ParameterizedType firstInterface = (ParameterizedType) interfaces[0];
        Class c = (Class) firstInterface.getActualTypeArguments()[0];
        System.out.println(c.getName()); // prints "AtomEntry"
    }
}

否则,您可以在getGenericInterfaces()及其actualTypeArguments中找到它们,直到找到与您正在寻找的内容相似的内容。

但如果您发现自己需要在实际代码中执行此操作,那么您的设计中可能会出现严重错误,或者您正在编写一些疯狂的天才模拟对象库,您不应该让我们回答这些问题。< / p>

答案 3 :(得分:0)

这里有一篇博文详细介绍:Reflecting Generics