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

mib*_*tec 5 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
  }
}
Run Code Online (Sandbox Code Playgroud)

使用Method.getReturnType()我得到java.lang.Object没有.方法"魔法"是否存在?

Mik*_*bel 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()
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

欢迎您使用我的图书馆.我实际上只是提交了一个错误修复程序,阻止了这个例子的工作(它在develop分支的尖端).


And*_*i I 1

不,那种魔法一般不存在。如果您想使用一些技巧来获取该数据,您可以在界面中要求该数据,如此处所述

另一方面,如果您的类型很特殊(例如列表),您可以这样做。对于特殊类型,请参阅此答案。