Я перепробовал все возможные способы получения класса универсального типа.
Таким образом, вы нашли здесь не работает для получения универсального:
public Reader() {
clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
, потому что он статически параметризованныйтип, определенный в непосредственном суперклассе Reader
, который в этом случае равен Object
.
Перемещение этого кода в конструкторе подкласса также не будет работать:
public ExcelReader() {
clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
, поскольку он извлекает статически параметризованный тип, определенный в классе Reader
, то естьT
.Поскольку T
не имеет никаких границ, вы все равно получите класс Object
в качестве возвращаемого класса.
Какое решение применить в вашем случае?
Дженерики стираются после компиляции.Таким образом, чтобы знать, что параметризованная информация о типе, используемая во время выполнения, равна Test
здесь:
Reader<Test> reader = new ExcelReader<>();
, вам необходимо явно «передать» Class
, представляющий универсальный код в вашем фактическом коде.
ToДля этого добавьте в конструктор параметр Class
, представляющий универсальный тип, и сохраните его в поле.Теперь у вас есть способ ссылаться на тип во время выполнения.
public class ExcelReader<T> extends Reader<T> implements RowColumnReader<T> {
private Class<T> genericType;
public ExcelReader(Class<T> genericType){
this.genericType = genericType;
}
/*...*/
}
Теперь вы можете создать экземпляр ExcelReader
следующим образом:
ExcelReader<Test> excelReader = new ExcelReader<>(Test.class);