如何使用Reflection获取方法的Generic Return类型

时间:2013-11-11 12:40:26

标签: java reflection

有没有办法获得泛型方法的返回类型 - 返回类型?

public interface MyGeneric<T> {
  T doSomething();
}

public interface MyElement extends MyGeneric<Element> {

}

public class Main {
  public static final void main(String[] args) {
    System.out.println(MyElement.class.getMethod("doSomething", new Class<?>[0]).magic()); // => Element
  }
}

使用Method.getReturnType()我得到java.lang.Object。方法“魔法”是否存在?

2 个答案:

答案 0 :(得分:6)

不幸的是,核心Java库中的反射功能对于分析泛型类型来说相当差。您可以使用getGeneric...方法(例如,getGenericReturnType()),但它们不能很好地工作,并且它们通常会返回Type个实例而不是Class个实例。我发现这非常笨拙。

我已经编写了自己的反射API,基于.NET,我觉得它更加一致(特别是在涉及泛型的地方)。请考虑以下输出:

import com.strobel.reflection.Type;

interface MyGeneric<T> {
    T doSomething();
}

interface Element {}

interface MyElement extends MyGeneric<Element> {}

class Main {
    public static final void main(String[] args) throws NoSuchMethodException {
        // prints "class java.lang.Object":
        System.out.println(
            MyElement.class.getMethod("doSomething").getReturnType()
        );
        // prints "T":
        System.out.println(
            MyElement.class.getMethod("doSomething").getGenericReturnType()
        );
        // prints "Element":
        System.out.println(
            Type.of(MyElement.class).getMethod("doSomething").getReturnType()
        );
    }
}

欢迎您使用my library。我实际上只提交了一个错误修复程序,阻止了这个例子的工作(它位于develop分支的顶端)。

答案 1 :(得分:1)

不,这种魔法一般不存在。如果您想制作一个技巧以获取该数据,您可以要求界面中的数据,如解释here

另一方面,如果您的类型是特殊的(如列表),您可以这样做。有关特殊类型,请参阅this answer