Java 如何在实例化T的子类时返回泛型类型T
我想得到一个参数化类,它能够返回类型为T的对象和T的子对象 代码如下:Java 如何在实例化T的子类时返回泛型类型T,java,generics,inheritance,Java,Generics,Inheritance,我想得到一个参数化类,它能够返回类型为T的对象和T的子对象 代码如下: import java.lang.reflect.InvocationTargetException; class A {}; class B extends A {}; public class testGenerics<T extends A> { T a; T getA() { return getA(B.class); // Compilation problem: //
import java.lang.reflect.InvocationTargetException;
class A {};
class B extends A {};
public class testGenerics<T extends A> {
T a;
T getA() {
return getA(B.class); // Compilation problem:
//The method getA(Class<T>) in the type testGenerics<T> is not applicable for the arguments (Class<B>)
}
T getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
}
我发现以下错误:
testGenerics为什么会这样?如何修复它?这不起作用,因为
B
不是T
。是的,B
也扩展了T
,但它不是T
。假设您还有一个类C扩展了一个,并创建了testGenerics
的实例。您的getA()
方法将实例化B
,但应返回C
。但是,通过一些调整,以下方法可以很好地工作:
testGenerics<B> tg = new testGenerics<B>();
B b = tg.getA(B.class);
但是,在这里不能真正使用t
(比如
)。由于T
是一种参数类型,因此您无法保证B
是否是或扩展T
您的问题是类定义类测试泛型
这意味着T
是在创建该类的实例时定义的,并且可以绑定到A
的任何子类,该子类可能不是B
,而是C
等。因此传递B.class
不能保证匹配
要解决此问题,请将T
的定义置于方法级别:
<T extends A> A getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
//No generics needed here, since the method above returns A anyways.
//If it'd return T you'd have to change the return type here to B since getA(B.class) binds T to be B now
A getA() throws Exception {
return getA(B.class);
}
getA(类clazz)抛出实例化异常、IllegaAccessException、IllegalArgumentException、InvocationTargetException、NoSuchMethodException、SecurityException{
返回clazz.getConstructor().newInstance();
}
//这里不需要泛型,因为上面的方法返回一个anyways。
//如果它返回T,您必须将这里的返回类型更改为B,因为getA(B.class)现在将T绑定为B
getA()抛出异常{
返回getA(B级);
}
由于方法级别T
隐藏了类级别的定义,因此您需要做一些事情:要么使用不同的名称(例如S
),要么删除类级别的定义(这在任何情况下都没有多大意义)。@Thomas这并不能解决报告的编译问题。对,看到了。问题有所不同:T
绑定到testGenerics
(应该是testGenerics
btw.)的实例,因此可能不是B
。
public <S extends A> S getA(Class<S> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
<T extends A> A getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
//No generics needed here, since the method above returns A anyways.
//If it'd return T you'd have to change the return type here to B since getA(B.class) binds T to be B now
A getA() throws Exception {
return getA(B.class);
}