泛型类中T.class的等价物是什么?

时间:2017-08-03 18:49:53

标签: java class generics

考虑以下通用转换器类(为简洁起见,简化/不完整)......

public abstract class BaseConverter <TModel>
{
    public void convert(String data, Class<TModel> classOfModelType)
    {
    }

    public void convert(String data)
    {
        convert(data, TModel.class); // This doesn't work!
    }
}

在子类外部,我可以毫无问题地调用第一个convert。考虑使用Car作为泛型类型参数的此子类。我可以传递Car.class,就像这样......

public class CarConverter extends BaseConverter<Car>
{
    public void someFunction()
    {
        String someString;
        convert(someString, Car.class);
    }
}

我想要做的是尽可能多地移动到基类。由于'Car'在这里是已知的,因此convert期望Car.class,而TModel代表基类中的Car(无论如何对于这个具体的BaseConverter),我试图使用基类中的TModel.class,但如上所述,它不起作用。

那么你如何在Java中实现这一目标呢?

3 个答案:

答案 0 :(得分:3)

通过在Class构造函数中接受它来存储对具体BaseConverter的引用。像这样:

public abstract class BaseConverter <TModel>
{
    private Class<TModel> clazz;

    public BaseConverter(Class<TModel> clazz) {
        this.clazz = clazz;
    }

    public void convert(String data, Class<TModel> classOfModelType)
    {
    }

    public void convert(String data)
    {
        convert(data, clazz); 
    }
}

public class CarConverter extends BaseConverter<Car>
{
    public CarConverter() {
        super(Car.class);
    }

    public void someFunction()
    {
        String someString;
        convert(someString, Car.class);
    }
}

答案 1 :(得分:2)

这是Java中泛型的限制。泛型只存在于编译时,即在运行时对象只是BaseConverter,因此您无法查询它的泛型类型。最简单的解决方案通常是在调用方法时传入Class<TModel>对象(正如您所做)。如果您不想多次传递它,也可以将它传递给BaseConverter的构造函数。

答案 2 :(得分:1)

在编译期间,泛型被擦除,并且在运行时不存在,因此T.class是不可能的。如果您的代码中包含BaseConverter<T>,那么它将在运行时变为BaseConverter<Object>

但你可以自己保存课程:

public abstract class BaseConverter <TModel> {
    private final Class<TModel> clazz;

    protected BaseConverter(Class<TModel> clazz) {
        this.clazz = clazz;
    }

    public void someFunction()
    {
        String someString;
        convert(someString, clazz); // use class here
    }
}

public class CarConverter extends BaseConverter<Car> {
    public CarConverter() {
        super(Car.class);
    }
}