给定两个接口:
public interface BaseInterface<T> { }
public interface ExtendedInterface<T0, T1> extends BaseInterface<T0> {}
和一个具体的类:
public class MyClass implements ExtendedInterface<String, Object> { }
如何找到传递给BaseInterface接口的类型参数?
(我可以通过调用下面的代码来检索ExtendedInterface类型的参数
MyClass.class.getGenericInterfaces()[0].getActualTypeArguments()
但我找不到一种简单的方法来递归到任何基本泛型接口中并获得任何有意义的结果)。
发布于 2009-02-21 15:07:42
这个问题一般不容易完全解决。例如,如果包含类是内部类,则还必须考虑包含类的类型参数。
因为仅使用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);
}
发布于 2009-02-17 17:45:24
我不知道你到底想要实现什么,什么是已知的,什么是未知的,但你可以像这样递归到超级界面:
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作为泛型参数。如果您知道ExtendedInterface
和BaseInterface
之间的关系,那么您就不必走那么远了,因为您知道前者的哪个泛型参数被传递给后者。如果不是,您可能必须遍历它们的参数并查找匹配项。基于此的东西可能是:
Type[] params = extInterfaceClass.getTypeParameters();
for (Type param : params) {
if (param == baseInterfaceType.getActualTypeArguments()[0]) {
// ...
}
}
发布于 2013-10-12 01:55:15
使用Java反射API很难解决这个问题,因为需要解析所有遇到的类型变量。从版本12开始,芭乐具有包含完全解析的类型信息的TypeToken类。
对于您的示例,您可以执行以下操作:
TypeToken<? extends T> token = TypeToken.of(MyClass.class);
ParameterizedType type =
(ParameterizedType) token.getSupertype(BaseInterface.class).getType();
Type[] parameters = type.getActualTypeArguments();
不过,您需要记住,这只适用于MyClass本身不是泛型的情况。否则,由于类型擦除,类型参数值在运行时不可用。
https://stackoverflow.com/questions/557663
复制相似问题