【发布时间】:2013-06-25 12:25:47
【问题描述】:
我有一个接口,其中有一个带有通用返回类型的方法,并且在运行时有一些类实例间接实现了该接口。现在我想使用反射找出每个实现的实际返回类型。
(我的想法是利用这种机制,通过接口定义策略,在运行时从一组策略实现中找到匹配的策略(具体返回类型),而不必引入冗余的辅助方法。暴露类型)。
更具体地说,让我们考虑以下场景:
private interface DAO <I extends Serializable, E> {
public E getById (I id);
}
private abstract class AbstractDAO <T> implements DAO<Integer, T> {
@Override
public T getById (Integer id) {
// dummy implementation, just for this example
return null;
}
}
private class PersonDAO extends AbstractDAO<Person> {
}
private class PersonDAOExtension extends PersonDAO {
}
在运行时,我想找出给定类 (PersonDAOExtension.class) 将为方法 getById(..) 返回的类型(预计为:Person.class)。
使用反射,我可以找出这个方法返回了哪个泛型Type。在这种情况下,它是 TypeVariable(但也可以是 Class,如果层次结构中的任何类会指定协变返回类型):
Method method = PersonDAOExtension.class.getMethod("getById", Integer.class);
Type genericReturnType = method.getGenericReturnType();
if (genericReturnType instanceof TypeVariable<?>) {
TypeVariable<?> typeVariable = (TypeVariable<?>) genericReturnType;
typeVariable.getName(); //results in "T"
}
我假设解析实际类型意味着递归到超类和接口,并将 raw (parameterizedType.getRawType()) 和 actual (parameterizedType.getActualTypeArguments()) 类型参数转换为任何参数化类型,直到找到所需的类型名称。
以前有没有人这样做过,也许有一些代码 sn-ps 可以帮助我实现这一点?非常感谢提前:)
提示:我能够在运行时使用反射提取以下信息,因此保留了原始和实际的类型信息:
private abstract interface DAO<I, E>
private abstract class AbstractDAO<T> extends Object implements DAO<Integer, T> [raw type:DAO<I, E>]
private class PersonDAO extends AbstractDAO<Person> [raw type:AbstractDAO<T>]
private class PersonDAOExtension extends PersonDAO
【问题讨论】:
-
一旦你知道类型,你想对它做什么?如果您打算使用
instanceof运算符,您可以改用if (Person.class.isAssignableFrom(method.getReturnType())) { ... } -
(非泛型)返回类型是 Object,所以这总是返回 false...
标签: java generics reflection