首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从泛型基接口的实例中检索类型参数

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

Stack Overflow用户
提问于 2009-02-17 16:37:48
回答 6查看 24.6K关注 0票数 20

给定两个接口:

代码语言:javascript
复制
public interface BaseInterface<T> { }
public interface ExtendedInterface<T0, T1> extends BaseInterface<T0> {}

和一个具体的类:

代码语言:javascript
复制
public class MyClass implements ExtendedInterface<String, Object> { }

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

(我可以通过调用下面的代码来检索ExtendedInterface类型的参数

代码语言:javascript
复制
MyClass.class.getGenericInterfaces()[0].getActualTypeArguments()

但我找不到一种简单的方法来递归到任何基本泛型接口中并获得任何有意义的结果)。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-02-21 15:07:42

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

因为仅使用Java本身提供的功能在泛型类型上进行反射是非常困难的,所以我编写了一个完成这项工作的库: gentyref。有关您的示例,请参阅http://code.google.com/p/gentyref/,使用gentyref,您可以执行以下操作:

代码语言:javascript
复制
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);
}
票数 20
EN

Stack Overflow用户

发布于 2009-02-17 17:45:24

我不知道你到底想要实现什么,什么是已知的,什么是未知的,但你可以像这样递归到超级界面:

代码语言:javascript
复制
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之间的关系,那么您就不必走那么远了,因为您知道前者的哪个泛型参数被传递给后者。如果不是,您可能必须遍历它们的参数并查找匹配项。基于此的东西可能是:

代码语言:javascript
复制
Type[] params = extInterfaceClass.getTypeParameters();
for (Type param : params) {
    if (param == baseInterfaceType.getActualTypeArguments()[0]) {
        // ...
    }
}
票数 6
EN

Stack Overflow用户

发布于 2013-10-12 01:55:15

使用Java反射API很难解决这个问题,因为需要解析所有遇到的类型变量。从版本12开始,芭乐具有包含完全解析的类型信息的TypeToken类。

对于您的示例,您可以执行以下操作:

代码语言:javascript
复制
TypeToken<? extends T> token = TypeToken.of(MyClass.class);
ParameterizedType type =
    (ParameterizedType) token.getSupertype(BaseInterface.class).getType();
Type[] parameters = type.getActualTypeArguments();

不过,您需要记住,这只适用于MyClass本身不是泛型的情况。否则,由于类型擦除,类型参数值在运行时不可用。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/557663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档