[英]How to return generic type T when instantiating a subclass of T
我想获取一个可以返回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:
//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();
}
}
我是这样想的:
我声明的是泛型T,它扩展了A。因此,我可以从Class clazz创建一个扩展了A的T类型的实例。
但是,当我决定从B.class获取A时(哪个扩展了A):
getA(B.class)
我收到以下错误:
类型为testGenerics <T>的方法getA(Class <T>)不适用于参数(Class <B>)
为什么是这样? 我该如何解决?
您的问题是类定义class testGenerics<T extends A>
。
这意味着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);
}
由于方法级别T
在类级别隐藏了定义,因此您需要为此做些事情:使用其他名称(例如S
)或在类级别删除定义(无论如何在这里都没有多大意义)。
这是行不通的,因为B
不是T
是的, B
也扩展了T
,但不是T
假设您还有一个类C extends A
并创建了一个testGenerics<C>
的实例。 您的getA()
方法将实例化B
但应返回C
但是,以下内容在进行一些调整后仍然可以正常工作:
testGenerics<B> tg = new testGenerics<B>();
B b = tg.getA(B.class);
如何解决此问题取决于您实际想要做什么。 例如,这允许您实例化A
任何子类:
public <S extends A> S getA(Class<S> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
但是,您实际上不能在这里使用T
(例如<S extends T>
)。 由于T
是参数类型,因此不能保证B
是T
还是扩展T
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.