在运行时通过反射获取泛型字段类型



我通过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():返回值为TTypeVariableImpl
  • field.getType()返回Object

我想访问Long作为字段类型。

我正在写一个供别人使用的库,有几个问题:

  1. 我实际上不知道类型是泛型类型还是常规类型,我只知道它是用@id注释的。
  2. 我不知道这个字段在类层次结构中的位置。

这是我用来获取类层次结构中所有字段的方法。

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);
    }
}

相关内容

  • 没有找到相关文章

最新更新