我无法通过id
的反射来访问MyClass
的运行时类型。
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()
:返回TypeVariableImpl
,其值为T
。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
的字段,其中只有一个。
答案 0 :(得分:3)
在运行时,泛型不是具体化。这意味着信息在运行时不存在。
一种方法是知道通用参数化类型的类类型,即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);
}
}
答案 1 :(得分:0)
使用TypeTools:
Type<?> t = TypeResolver.resolveRawArgument(AbstractEntity.class, MyClass.class);
assert t == Long.class
干杯