我通过MyClass
的反射访问id
的运行时类型有困难。
public abstract class AbstractEntity<T> {
@Id
private T id; //I need to access the runtime class of T
}
public class MyClass extends AbstractEntity<Long> {}
我正在使用java反射,并且可以访问超类中的id Field
。
我试着使用:
-
field.getGenericType()
:返回值为T
的TypeVariableImpl
。 -
field.getType()
返回Object
我想访问Long
作为字段类型。
我正在写一个供别人使用的库,有几个问题:
- 我实际上不知道类型是泛型类型还是常规类型,我只知道它是用
@id
注释的。 - 我不知道这个字段在类层次结构中的位置。
这是我用来获取类层次结构中所有字段的方法。
private Set<Field> getAllFields(final Object object) {
final Set<Field> fields = new HashSet<>();
fields.addAll(Arrays.asList(object.getClass().getDeclaredFields()));
Class<?> superclass = object.getClass().getSuperclass();
while (superclass != null) {
fields.addAll(Arrays.asList(superclass.getDeclaredFields()));
superclass = superclass.getSuperclass();
}
return fields;
}
然后,我过滤这个列表,以@Id
注释的字段,其中应该只有一个。
泛型在运行时没有具体化。这意味着信息在运行时不存在。
一种方法是知道泛型参数化类型的类类型,即Class<T> entityClass
。
有几种方法可以实现这一点。您可以使用默认构造函数并反射地获取类类型:
this.entityClass= (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
或者创建一个构造函数,在构造函数上传递Generic类类型:
protected AbstractEntity(Class<T> entityClass) {
this.entityClass = entityClass;
}
然后,您的具体实体类可以默认传递其类类型,如下所示:
public class MyClass extends AbstractEntity<Long> {
public MyClass() {
super(Long.class);
}
}