2009-08-12 4 views
1

昨日、ジェネリッククラスの非静的な内部クラスに属するオブジェクトの配列を作成しようとしました。そうする良い方法はないようです。この一般的な配列を初期化するためのよりクリーンな方法はありますか?


初の試み:

public class Wibble<T>{ 
     public static void main(String...args){ 
      new Wibble<String>(); 
     } 
     public Wibble(){ 
      Bar[] bar = new Bar[11]; 
     } 
     static class Foo{} 
     class Bar extends Foo{} 
} 

これは動作しません、 'Wibble' の文脈の中で 'バー' は、次のエラーが生じ、暗黙のうちにジェネリックですので:

Exception in thread "main" java.lang.Error: 
Unresolved compilation problem: Cannot create a generic array of Wibble<T>.Bar 

at Wibble.<init>(Wibble.java:7) 
at Wibble.main(Wibble.java:4) 

2回目の試行:

public class Wibble<T> { 
     public static void main(String...args){ 
      new Wibble<String>(); 
     } 
     public Wibble(){ 
      Bar[] bar = (Bar[])new Foo[11]; 
     } 
     static class Foo{} 
     class Bar extends Foo{} 
} 

配列は最新の既知の非ジェネリック型の汎用型にのみキャストできるため、これは機能しません。ジェネリックバーでは、最も最近知られている非ジェネリックタイプは非ジェネリックバーです。これは、親クラスのコンテキスト内で(簡単に)参照することはできません。次のエラーが生じ:

Exception in thread "main" java.lang.ClassCastException: 
[LWibble$Foo; cannot be cast to [LWibble$Bar; 

at Wibble.<init>(Wibble.java:7) 
at Wibble.main(Wibble.java:4) 

最後の試み:これは、コンストラクタ内で配列を作成したい場合、あなたはまた、(プライベート)ダミーを必要とする、しかし、作品

public class Wibble<T> { 
     private static final Class<?> BARCLASS = new Wibble<Object> (false).new Bar().getClass(); 
     public static void main(String...args){ 
      new Wibble<String>(); 
     } 
     private Wibble(boolean flag){} 
     public Wibble(){ 
      Bar[] bar = (Bar[])Array.newInstance(BARCLASS, 11); 
     } 
     static class Foo{} 
     class Bar extends Foo{} 
} 

あなたがクラスを得ることができるようにコンストラクタ。
さらに、親クラスが抽象クラスの場合、すべての抽象メソッドに対してダミーの実装を提供する必要があります。


私はこれを書き終えたとして、私も作品

public class Wibble<T> {  
     public static void main(String...args){ 
      new Wibble<String>(); 
     } 
     private Wibble(boolean flag){} 
     public Wibble(){ 
      Bar[] bar = (Bar[])Array.newInstance(Bar.class, 11); 
     } 
     static class Foo{} 
     class Bar extends Foo{} 
} 
ことに気づき、そして私もまだ投稿かもしれない考え出しました。まだまだ醜いですが、通常の構文が機能しないという事実に対する正当性はありません。

+0

再フォーマットされましたが、正確に何が問題なのですか? –

+0

あなたの最初の例は私にとってうまくコンパイルされます。私は暗黙の意味が何であるかを知っているかどうか分からず、あなたの例にジェネリックはありません。スタックオーバフローによって "<" and ">"が削除されていますか? ( "format as code"ボタンを使用してください)。 –

+0

@ Steve B. Barクラスを非静的にしてもよろしいですか? クラスバーは一般的です。 Wibble内にWibble wibbleがあるとしましょう(Barは非静的な内部クラスであるため)、暗黙のジェネリックタイプの 'String'を持っています。 –

答えて

2

あなたもBarとして静的クラスを宣言した場合、次のコード(すなわち最も明白な)う、コンパイル時と実行時の両方の作品:

Bar[] bar = new Bar[11]; 

EDITれるjava.langを使用して

.reflect.Array.newInstanceは、実行時に新しいジェネリック配列を割り当てるための好ましい方法です

+0

実際のコードでは、非静的な内部クラスには親クラスのジェネリック型のインスタンスが含まれていたため、Barは静的ではありませんでした。 あなたの編集に関しては、私の主な問題は、配列が一般的なものとみなされているという事実です。アレイのランタイムタイプは簡単に推測できます。私はそれが事実であるとき何か問題があるべきではないと思います。 –

+0

"java.lang.reflect.Array.newInstanceを使用して..."いいえコンポーネントクラス(Bar)はコンパイル時に認識されます。 – newacct

2

"暗黙的な一般性"を維持する必要がある場合、つまりクラスを静的にすることはできませんあなたはそれについて警告を受けるでしょうが、あなたはBar[] bar = new Bla.Bar[11];をすることができます。

1
List<Bar> bars = new ArrayList<Bar>(); 

ソート(er、ordered)。