2013-05-19 4 views
9

さまざまな理由から、リストを配列に変換したいのですが、コレクションにはジェネリックのオブジェクトが含まれています。generic型のコレクションを配列に安全に変換する方法は?

@supressWarnings( '未チェック')の注釈は必要ありませんが、コンパイルするために次の4つのオプションを試しましたが、いずれも機能しません。この問題を解決するソリューションはありますか、または注釈を使用する必要がありますか?

Iterator<T>[] iterators; 
final Collection<Iterator<T>> initIterators = new ArrayList<Iterator<T>>(); 

// Type safety: Unchecked cast from Iterator[] to Iterator<T>[] 
iterators = initIterators.<Iterator<T>>toArray(
     (Iterator<T>[])new Iterator[initIterators.size()]); 

// Type safety: Unchecked invocation toArray(Iterator[]) of the generic 
// method toArray(T[]) of type Collection<Iterator<T>> 
// Type safety: The expression of type Iterator[] needs unchecked conversion 
// to conform to Iterator<T>[] 
iterators = initIterators.<Iterator<T>>toArray(
     new Iterator[initIterators.size()]); 

// Type safety: The expression of type Iterator[] needs unchecked conversion 
// to conform to Iterator<T>[] 
iterators = initIterators.toArray(new Iterator[initIterators.size()]); 

// Doesn't compile 
iterators = initIterators.toArray(new Iterator<T>[initIterators.size()]); 
+0

多分[[This(http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#FAQ104)]少し助けてください。とにかく、なぜArrayList(ArrayList)の代わりにArray(ジェネリックをサポートしていない)を使用したいのか興味があります。 – Pshemo

+0

[Array of Generic List](http://stackoverflow.com/questions/7810074/array-of-generic-list)の可能な複製。参照:[複数の子を持つツリーの配列の汎用型](http://stackoverflow.com/questions/15957325/generic-types-in-an-array-for-a-tree-with-more) - 1歳未満の子供)。 –

+0

@PaulBelloraあなたがリストアップした質問は重複していないと思いますが、同様の内容について話します。 –

答えて

12

などIterator<T>[]としてパラメータタイプの配列を作成するには何のタイプセーフな方法はありません。

また、生の配列:Iterator<?>[]を作成することもできます。または、配列の使用を完全に避けることができる場合は、List<Iterator<T>>のようなコレクションタイプを使用してください。

なぜなら、Java配列は共変であり、汎用型のパラメータ化された境界は不変であるからです。 DoubleNumber延びており、numbersの宣言された型がNumber[]あるので

Integer[] integers = new Integer[1]; 
Number[] numbers = integers; // OK because Integer extends Number 
numbers[0] = new Double(3.14); // runtime exception 

コンパイラが割り当てることができます:それは言うことです。しかし、実行時には、実際の配列オブジェクトインスタンスは元のInteger[1]であり、配列にはオブジェクトのタイプが含まれています。

ジェネリックでは、パラメータ化された型が異なります。 1つは、のコンパイル時の型消去のため、は実行時の型を本質的に知らない。ジェネリック医薬品と

List<Integer> integerList = new ArrayList<Integer>(); 

List<Number> numberList = integerList; // compiler error, prevents: 
numberList.add(new Double(3.14)); // would insert a Double into integerList 

Collection<Integer> integerCollection = integerList; // allowed 
// OK because List extends Collection and the <type parameter> did not change 

Collection<Number> numberCollection = integerList; // compiler error 
// an "Integer" is a "Number" 
// but "a collection of Integers" is more specific than "a collection of Numbers" 
// and cannot be generally treated the same way and guarantee correct behavior 

List<?> rawList = integerList; // allowed, but... 
rawList.add(new Integer(42)); // compiler error, Integer is not a ... a what? 

、Javaで、あなたはジェネリック型が正しいと安全であることを検証するために、コンパイラ(ないランタイム)に依存しています。 Iterator<?>[]はそれがIteratorの要素を含む配列で、実行時に知っていながら

だから、Iterator<T>[]<T>は、コンパイル時にを消去され、ランタイムは、それが可能になっていたかを知る方法がありません。だからあなたは未確認の警告を受ける。

+0

+1良い説明。 –

+0

良い説明ですが、残念ながらそれは私を助けません。私はコレクション>を持っていますが、私はイテレータを必要とします []。前者を後者に変換したいのですが、そうすることはできますが、コンパイラの警告なしに行うことはできません。私が取り除きたいのはこの警告だけです。 –

+0

@PaulWagland:何らかの警告(コードや関数の中のいずれか)を抑制することなく、 'Iterator []'型の非ヌル値を得ることは不可能です – newacct

関連する問題