我有一个泛型类,其方法调用另一个方法,该方法需要一个类对象作为其参数之一。我希望能够使用在对象创建时设置为泛型的类类型,但我似乎无法使语法正确。这就是我想做的事情:
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个版本中是否存在语法错误?这是不能做的事情吗?
希望这一切都有意义。
答案 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);
}