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

2022-09-02 09:44:36

给定 2 个接口:

public interface BaseInterface<T> { }
public interface ExtendedInterface<T0, T1> extends BaseInterface<T0> {}

和一个具体类:

public class MyClass implements ExtendedInterface<String, Object> { }

如何找出传递给 Base 接口的类型参数?

(我可以通过调用类似的东西来检索扩展接口类型参数

MyClass.class.getGenericInterfaces()[0].getActualTypeArguments()

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


答案 1

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

因为使用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);
}

答案 2

我不知道你到底想达到什么目的,知道什么,不知道什么,但你可以像这样递归到超接口:

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();

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

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