在方法中使用泛型类类型

时间:2012-10-11 15:06:53

标签: java generics

我有一个泛型类,其方法调用另一个方法,该方法需要一个类对象作为其参数之一。我希望能够使用在对象创建时设置为泛型的类类型,但我似乎无法使语法正确。这就是我想做的事情:

public abstract class GenericClass<T> {

    private void doStuff() {
        //do a bunch of stuff

        //This method's signature is methodToCall(Serializable s) and is not a method I can change
        methodToCall(T);
        methodToCall(Class<T>);
        methodToCall(T.class);

        //do some more stuff
    }

}

public class NonGenericClass extends GenericClass<DesiredClass> {

}

Class对象类型是可序列化的,因此可以工作:

methodToCall(DesiredClass.class);

但我无法轻易覆盖该方法,因为我最终会复制所有代码,因为在方法中间需要类类型。

这是迄今为止我提出的最好的方法:

public abstract class GenericClass<T> {

    protected abstract void doStuff();

    protected <T> void doStuff(Class<T> cls) {
        methodToCall(cls);
    }

}

public class NonGenericClass extends GenericClass<DesiredClass> {

    @Override
    protected void doStuff() {
        doStuff(DesiredClass.class);
    }

}

这有效,但感觉泛型类浪费了它具有T的知识。在我首先列出的调用methodToCall的3个版本中是否存在语法错误?这是不能做的事情吗?

希望这一切都有意义。

3 个答案:

答案 0 :(得分:2)

如果要调用其参数实现任何类型的方法,则必须确保通用类型,T实现/扩展该类型。

public class GenericClass<T extends Serializable>
{
    // ...
}

答案 1 :(得分:2)

GenericClass需要运行时类型标记:传递给其构造函数并保存在字段中的Class<T>对象。代码与您的最佳尝试大致相同,但更标准:

class GenericClass<T> {

    Class<T> clazz;

    public GenericClass(Class<T> c) {
        clazz = c;
    }

    protected void doStuff() {
        methodToCall(clazz);
    }

}

答案 2 :(得分:0)

在这种情况下,如果您知道对象的实际运行时类总是以实际类作为类型参数来实现GenericClass,那么您可以从类的元数据中检索该类型参数(这里我们假设实际的类是GenericClass的直接子类,以简化搜索):

private void doStuff() {
    Class<T> clazz = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    methodToCall(clazz);
}