Java泛型问题

时间:2011-01-26 13:27:49

标签: java generics

我遇到了泛型的以下问题。我希望子类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);
 }
}

7 个答案:

答案 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)

这是一个完整的例子吗?我没有看到在任何地方创建AAA的任何实例。如果您希望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);
 }
}