簡體   English   中英

通過反射在運行時獲取通用字段類型

[英]Get generic field type at runtime via reflection

我無法通過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作為字段類型。

我正在為其他人編寫一個庫,但有一些問題:

  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類型,即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);
    }
}

使用TypeTools

Type<?> t = TypeResolver.resolveRawArgument(AbstractEntity.class, MyClass.class);
assert t == Long.class

干杯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM