从通用基接口的实例中检索类型参数

And*_*ndy 20 java generics reflection

给出2个接口:

public interface BaseInterface<T> { }
public interface ExtendedInterface<T0, T1> extends BaseInterface<T0> {}
Run Code Online (Sandbox Code Playgroud)

和一个具体的类:

public class MyClass implements ExtendedInterface<String, Object> { }
Run Code Online (Sandbox Code Playgroud)

如何找到传递给BaseInterface接口的类型参数?

(我可以通过调用类似的东西来检索ExtendedInterface类型参数

MyClass.class.getGenericInterfaces()[0].getActualTypeArguments()
Run Code Online (Sandbox Code Playgroud)

但我无法找到一种简单的方法来递归到任何基础通用接口并得到任何有意义的东西).

Wou*_*rts 20

这个问题一般不容易完全解决.例如,如果它是一个内部类,你还必须考虑包含类的类型参数,...

因为只使用Java本身提供的对泛型类型的反思是如此困难,所以我编写了一个完成艰苦工作的库:gentyref.请参阅http://code.google.com/p/gentyref/ 对于您的示例,使用gentyref,您可以执行以下操作:

Type myType = MyClass.class;

// get the parameterized type, recursively resolving type parameters
Type baseType = GenericTypeReflector.getExactSuperType(myType, BaseInterface.class);

if (baseType instanceof Class<?>) {
    // raw class, type parameters not known
    // ...
} else {
    ParameterizedType pBaseType = (ParameterizedType)baseType;
    assert pBaseType.getRawType() == BaseInterface.class; // always true
    Type typeParameterForBaseInterface = pBaseType.getActualTypeArguments()[0];
    System.out.println(typeParameterForBaseInterface);
}
Run Code Online (Sandbox Code Playgroud)


gix*_*gix 6

我不知道你究竟想要实现什么,知道什么,不知道什么,但你可以像这样递归到超级接口:

Type[] interfaces = MyClass.class.getGenericInterfaces();

ParameterizedType extInterfaceType = (ParameterizedType)interfaces[0];
Class<?> extInterfaceClass = (Class<?>)extInterfaceType.getRawType();

Type[] baseInterfaces = extInterfaceClass.getGenericInterfaces();
ParameterizedType baseInterfaceType = (ParameterizedType)baseInterfaces[0];
Class<?> baseInterfaceClass = (Class<?>)baseInterfaceType.getRawType();
Run Code Online (Sandbox Code Playgroud)

当然,如果以这种方式达到第二级,则只能将名称T0和T1作为通用参数.如果你知道它们之间的关系ExtendedInterface,BaseInterface那么你真的不必走得那么远,因为你知道前者的哪个泛型参数传递给后者.如果没有,您可能需要遍历其参数并找到匹配项.可能基于此的东西:

Type[] params = extInterfaceClass.getTypeParameters();
for (Type param : params) {
    if (param == baseInterfaceType.getActualTypeArguments()[0]) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)