簡體   English   中英

Java泛型問題

[英]Java Generics problem

我一直堅持使用泛型的以下問題。 我希望子類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);
 }
}

如果您想要在標記的位置創建類型參數T的實例,那么不幸的是,使用Java泛型是不可能的(由於type erasure )。

如果您還想要其他東西,請澄清。

我會使用工廠界面:

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);
 }
}

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);
 }
}

這是一個完整的例子嗎? 我看不到任何地方創建AAA任何實例。 如果您希望System.out行打印“It works_itchy”,則需要至少創建AA實例。

T代表類B中AA的一個實例。您需要傳入一個AA的實例,也許是在構造函數中傳遞:

public B(T aaInstance) {
   this.field = T;
}

由於類型擦除,您無法在運行時創建AA實例,如果這是您要查看的內容,因為編譯后類型不可用。

可能(但確實很奇怪):

ParameterizedType pt = (ParameterizedType) getClass().getGenericSuperclass();
Class<?> cls = (Class<?>) pt.getActualTypeArguments()[0];
field =  (T) cls.getConstructor(String.class).newInstance(name);
return field;

另一種選擇是將T getField(String) (以及B)用於抽象和強制BB來提供實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM