Java反射:获取实现泛型接口的具体类型

9
说我有一个如下所示的类:
public class AtomEntryHandler implements ConsumingHandler<AtomEntry>
{
...
}

能否从AtomEntryHandler.class类对象中获取AtomEntry.class类对象?

我认为由于擦除的原因这是不可能的,但我的朋友说可以。


你的朋友说了吗?怎么做的? - Dave Newton
Alex Gitelman的回答对你有用吗? - Ray Toal
4个回答

10

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

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

2
我在文档中读到有关接口的内容,但如果类像问题中实现了参数化接口(并且没有显式扩展任何类),则在将其转换为ParameterizedType时,您将得到java.lang.Object和强制转换异常。 - Alex Gitelman
如果您调用getGenericSuperclass()并且您没有明确扩展任何内容或者您扩展非泛型类,那么这是正确的,但是如果您调用getGenericInterfaces(),那么类层次结构就无关紧要了,因为它只涉及接口。 - Chris Hannon

5

在接口实现的情况下,我找不到一种确定基本类型参数的方法(这并不意味着没有)。但是这就是最接近它的方式。

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

结果: java.lang.Integer类


2
如果你知道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中查找,直到找到类似于您要查找的内容。
但是,如果您发现自己需要在实际代码中执行此操作,那么可能您的设计出了严重问题,或者您正在编写一些疯狂的天才模拟对象库,您不应该需要我们回答这些问题。

是的,我试着使用它,但它只会让代码变得比必要的复杂。如果简单一些,它只会避免一些重复。 - ekj

0

这里有一篇博客文章详细介绍了它:反射泛型


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接