我有两个类和一个接口
public class ExcelReader<T> extends Reader<T> implements RowColumnReader<T> {
// private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {};
// private final Type type = typeToken.getType();
/* public Type getType() {
return type;
}*/
// Useing Guava getting System.out.println(reader.getType()) T as ouput
@Override
public List<T> readFile(String file) {
//my code
}
}
public abstract class Reader<T> {
protected Class<T> clazz;
/*public Reader() {
clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}*/
// Constructor is commented beacuse getting Exception java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
}
public interface RowColumnReader<T> extends HeaderFields<T>{
public List<T> readFile(String file);
}
public interface HeaderFields<T> {
default List<String> getHeader(Class<T> clazz) throws HeaderNotDefiendException {
//my code
return headerList;
}
}
我已经尝试了所有可能的方法来获取泛型类型的类。我关注了Get generic type of class at runtime 甚至尝试了该页面中给出的所有解决方案。但仍然没有任何运气。
甚至和Gauva一起
https://stackoverflow.com/a/19775924/2290078
得到getType()
的输出不是实际的通用类
我的测试代码是
Reader<Test> reader = new ExcelReader<>();
//System.out.println(reader.getType()); ---> output is T
List<Test> list = reader.readFile("Sample.xlsx");
System.out.println(list);
答案 0 :(得分:2)
这不仅仅是“我应该在运行时使用哪种API来获取通用类型?”的问题。这取决于您要对通用类型(T
)做些什么。
泛型更多地是一种编译时检查功能,可以使用T extends
和T super
施加一些有用的限制。而已。
这可能很有用Difference between <? super T> and <? extends T> in Java
如果您想在运行时知道类型T
,并使用switch
之类的条件进行实现,那么您所定义的泛型类实际上并不是真正的泛型类,因为实现方式因类型不同,因此无法正常支持。
答案 1 :(得分:1)
我已经尝试了所有可能的方法来获取泛型类型的类。
您发现here的这种方式无法检索通用:
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
。
为此,请在构造函数中添加一个表示通用类型的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);