我有一个泛型类,Foo<T>。在Foo的一个方法中,我想获取T类型的类实例,但我无法调用T.class。

使用T.class绕过它的首选方法是什么?


当前回答

我想将T.class传递给一个使用Generics的方法

readFile方法读取文件名指定的.csv文件,文件名为fullpath。可以有不同内容的csv文件,因此我需要传递模型文件类,以便获得适当的对象。因为这是读取csv文件,所以我想以通用的方式进行。由于某种原因或其他原因,上述解决方案都不适用于我。我需要使用类别<?扩展T>类型以使其工作。我使用opencsv库解析CSV文件。

private <T>List<T> readFile(String fileName, Class<? extends T> type) {

    List<T> dataList = new ArrayList<T>();
    try {
        File file = new File(fileName);

        Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        Reader headerReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

        CSVReader csvReader = new CSVReader(headerReader);
        // create csv bean reader
        CsvToBean<T> csvToBean = new CsvToBeanBuilder(reader)
                .withType(type)
                .withIgnoreLeadingWhiteSpace(true)
                .build();

        dataList = csvToBean.parse();
    }
    catch (Exception ex) {
        logger.error("Error: ", ex);
    }

    return dataList;
}

这是readFile方法的调用方式

List<RigSurfaceCSV> rigSurfaceCSVDataList = readSurfaceFile(surfaceFileName, RigSurfaceCSV.class);

其他回答

比其他人建议的类更好的方法是传入一个对象,该对象可以执行您对类所做的操作,例如创建一个新实例。

interface Factory<T> {
  T apply();
}

<T> void List<T> make10(Factory<T> factory) {
  List<T> result = new ArrayList<T>();
  for (int a = 0; a < 10; a++)
    result.add(factory.apply());
  return result;
}

class FooFactory<T> implements Factory<Foo<T>> {
  public Foo<T> apply() {
    return new Foo<T>();
  }
}

List<Foo<Integer>> foos = make10(new FooFactory<Integer>());

简单的答案是,无法找出Java中泛型类型参数的运行时类型。我建议阅读Java教程中有关类型擦除的章节以了解更多详细信息。

对此,一个流行的解决方案是将类型参数的Class传递给泛型类型的构造函数,例如。

class Foo<T> {
    final Class<T> typeParameterClass;

    public Foo(Class<T> typeParameterClass) {
        this.typeParameterClass = typeParameterClass;
    }

    public void bar() {
        // you can access the typeParameterClass here and do whatever you like
    }
}

我在抽象泛型类中遇到了这个问题。在这种特殊情况下,解决方案更简单:

abstract class Foo<T> {
    abstract Class<T> getTClass();
    //...
}

以及随后的派生类:

class Bar extends Foo<Whatever> {
    @Override
    Class<T> getTClass() {
        return Whatever.class;
    }
}

实际上,我想你的类中有一个T型字段。如果没有T型字段,那么有一个泛型类型有什么意义?因此,您可以简单地在该字段上执行实例化。

在我的情况下,我有一个列表<T>项;在我的类中,我检查类类型是否为“Locality”

if (items.get(0) instanceof Locality) ...

当然,这只在可能的类总数有限的情况下有效。

你不能这样做,因为类型删除。另请参阅堆栈溢出问题Java泛型-类型擦除-何时发生以及发生什么。