Java 运行时获取类的泛型类型无效

Java 运行时获取类的泛型类型无效,java,generics,reflection,Java,Generics,Reflection,我有两个类和一个接口 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 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;
    }

}

这不仅仅是“我应该使用什么API在运行时获取泛型类型?”的问题。这取决于您想对泛型类型(
T
)执行什么操作

泛型更像是一种编译时检查功能,可以使用
T extends
T super
施加一些有用的限制。就这样。 这可能有用


如果您想在运行时了解类型
T
,并使用类似
开关的东西执行条件实现,那么您声明的泛型类在定义上并不是真正的泛型类,因为不同类型的实现不同,因此它不受支持。

这不仅仅是一个问题“我应该使用什么API在运行时获取泛型类型?”。这取决于您希望如何处理泛型类型(
T

泛型更像是一种编译时检查功能,可以使用
T extends
T super
施加一些有用的限制。 这可能有用

如果您想在运行时了解类型
T
,并使用类似
开关的东西执行条件实现,那么您声明的泛型类在定义上并不是真正的泛型类,因为不同类型的实现不同,因此不支持它

我已经尝试了所有可能的方法来获得泛型类型的类

您发现的这种方式无法检索泛型:

public Reader() {
    clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
当它静态地检索
读取器
类中定义的参数化类型时,即
T
。由于
T
没有任何绑定,您仍然将
对象
类作为返回的类

在您的案例中应用哪种解决方案?

编译后,泛型将被删除。因此,请注意,运行时使用的参数化类型信息是
Test
,此处:

Reader<Test> reader = new ExcelReader<>();
现在,您可以通过以下方式实例化
ExcelReader

ExcelReader<Test> excelReader = new ExcelReader<>(Test.class);
ExcelReader=新的ExcelReader(Test.class);
我已经尝试了所有可能的方法来获得泛型类型的类

您发现的这种方式无法检索泛型:

public Reader() {
    clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
当它静态地检索
读取器
类中定义的参数化类型时,即
T
。由于
T
没有任何绑定,您仍然将
对象
类作为返回的类

在您的案例中应用哪种解决方案?

编译后,泛型将被删除。因此,请注意,运行时使用的参数化类型信息是
Test
,此处:

Reader<Test> reader = new ExcelReader<>();
现在,您可以通过以下方式实例化
ExcelReader

ExcelReader<Test> excelReader = new ExcelReader<>(Test.class);
ExcelReader=新的ExcelReader(Test.class);

我也在使用相同的选项。但我一直在寻找更好的选项。啊?虽然这不是你在发布的代码中写的。你还告诉我它不起作用,但你没有告诉我你搜索了更好的选项。我试图用给定链接中的解决方案创建util类,你可能没有看到关于这个答案的评论:“这种技术适用于在直接超类上定义类型参数的情况“。在您的类中,类型是在当前类中定义的,而不是在超类中定义的。我使用的是相同的。但是我在寻找一个更好的选择。啊?虽然这不是你在张贴的代码中写的。您还告诉我它不起作用,您没有告诉我您搜索了一个更好的选项。我试图用解决方案创建util类,就像在给定的链接中一样,您可能没有看到关于此答案的注释:。“当类型参数在直接超类上定义时,这种技术就起作用了”。在您的类中,类型是在当前类中定义的,而不是在超类中定义的。谢谢。现在,我明白了这甚至是不可能的@davidxxx的答案是唯一的解决方案。很乐意帮助。此外,他提到的技巧经常被使用,但这违背了类是泛型的目的。如果您有兴趣,可以通过Collections框架和Spring核心代码来演示类应该是泛型的更好示例。谢谢。现在,我明白了这甚至是不可能的@davidxxx的答案是唯一的解决方案。很乐意帮助。此外,他提到的技巧经常被使用,但这违背了类是泛型的目的。如果您有兴趣,可以通过Collections框架和Spring核心代码演示类应该是泛型的更好示例。