2011-01-26 15 views
0

ジェネリックスに次の問題があります。私はスーパークラスBのメソッドを使って、スーパークラスBのフィールドの1つであるAのサブクラスのインスタンスを取得するサブクラスBBを求めています。誰かがこの問題を処理する最善の方法を教えてください。Javaジェネリックスの問題

下記のコードを実行してください(コメントは//こちらを参照してください)、それは自己説明的であり、とにかくそれを言葉にする方法はわかりません。

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のインスタンスを作成にある場合、それは(type erasureに起因する)は、Javaのジェネリックで、残念ながらできません。

あなたが望むものが他にある場合は、明確にしてください。

+0

場合によっては可能です。ジェネリックparamを持つクラスが抽象クラスの場合、リフレクションを使用して型を取得してインスタンスを作成できますが、これは危険です。 –

0

完全な例ですか?どこでも作成されているAまたはAAのインスタンスは表示されません。 System.out行に "It works_itchy"と表示されることが予想される場合は、少なくともAAのインスタンスを作成する必要があります。

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

型消去のなので、あなたがAAのインスタンスでは作成できません:

0

Tは、あなたは多分、コンストラクタでは、AAのインスタンスを渡す必要があるだろう、クラスBのAAのインスタンスを表しコンパイル後に型が使用できないため、実行する必要がある場合は実行時に使用します。それは可能(ただし、本当に奇妙な)である

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

私は、このためにfactoryインタフェースを使用することになり、抽象

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

0

別のオプションは、(Bのために、そこに)T getField(String)を残すことで、実装を提供するようにBBに指示します。

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); 
} 
} 
関連する問題