我遇到了泛型的以下问题。我希望子类BB通过超类B中的方法获取A的子类的实例,这是其超类B的字段之一。有人可以请告诉我处理此问题的最佳方法
请仔细阅读下面的代码(请参阅评论//此处有问题),这是自我解释的,我不知道如何将其放入文字中。
public class A {
String name;
A(String name){
this.name = name;
}
}
public class AA extends A{
String itchy
AA(String name) {
super(name);
this.itchy = name+"_itchy";
}
}
public class B<T extends A> {
T field;
T getField(String name) throws InstantiationException, IllegalAccessException{
//Problem here
field = // instance of AA; how do i do this?
return field;
}
}
public class BB extends B<AA>{
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
BB b = new BB();
System.out.println(b.getField("It works").name);
}
}
答案 0 :(得分:1)
如果你想要的是在标记的地方创建类型参数T
的实例,遗憾的是,Java泛型不可能(由于type erasure)
如果您想要的是其他内容,请澄清。
答案 1 :(得分:1)
我会使用factory接口:
public interface Factory<T extends AA> {
T create(String name);
}
public class AAFactory implements Factory<AA> {
AA create(String name) {
return new AA(name);
}
}
public class B<T extends A> {
B(Factory<T> factory) {
this.factory = factory;
}
Factory<T> factory;
T field;
T getField(String name) {
field = factory.create(name);
return field;
}
}
public class BB extends B<AA>{
BB() {
super(new AAFactory());
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
BB b = new BB();
System.out.println(b.getField("It works").name);
}
}
答案 2 :(得分:0)
这是一个完整的例子吗?我没有看到在任何地方创建A
或AA
的任何实例。如果您希望System.out
行打印“It works_itchy”,则需要至少创建AA
的实例。
答案 3 :(得分:0)
T表示B类中AA的一个实例。您需要传入一个AA实例,可能是在构造函数中:
public B(T aaInstance) {
this.field = T;
}
由于类型擦除,您无法在运行时创建AA实例(如果这是您要执行的操作),因为编译后类型不可用。
答案 4 :(得分:0)
有可能(但很奇怪):
ParameterizedType pt = (ParameterizedType) getClass().getGenericSuperclass();
Class<?> cls = (Class<?>) pt.getActualTypeArguments()[0];
field = (T) cls.getConstructor(String.class).newInstance(name);
return field;
答案 5 :(得分:0)
另一个选择是留下T getField(String)
(并且那里是B)摘要和强制BB来提供实现。
答案 6 :(得分:0)
B需要它创建的类的副本。子类将其传递给构造函数。
public class B<T extends A> {
final Class<T> classT;
B(Class<T> classT) { classT=classT; )
T field;
T getField(String name) throws InstantiationException, IllegalAccessException{
//Problem here
field = classT.newInstance();
return field;
}
}
public class BB extends B<AA>{
BB() { super(AA.class); }
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
BB b = new BB();
System.out.println(b.getField("It works").name);
}
}