2011-10-26 1 views
27

のJava 1.6は、この動作を持っている理由は誰もが知っています:リスト<String> .toArray()がString []ではなくObject []を返すのはなぜですか?これを回避するには?

List<String> list = ArrayList<String>(); 
String[] arr = (String[]) list.toArray(); 

そして、それがString [] []オブジェクトを返し、ないので、私は、ClassCastExceptionが取得します。

私は List<T>.toArray()がT [] - を返すと思いましたか?この不便さがなぜ言語に存在するのか誰にも答えがありますか? また、これを回避する方法もありますか?どのようにしてList<String>からアイテムをループせずにString []を取得できますか?

+2

Jave」はdoesnの本当に 'T []'の概念を持っています。 – Gabe

+0

[java:(String \ [\])List.toArray()はClassCastExceptionを返す可能性があります(http://stackoverflow.com/questions/5690351/java-stringlist-toarray-gives-classcastexception) –

答えて

20

ランタイムタイプをヒントとしてtoArrayで使用できるように、配列を渡す必要があります。代わりにtoArray(new String[0])を試してください。また、あらかじめサイズの決められた配列を渡すこともできます。

は、理解

new T[4] 

仕事をするために行う必要がありますどのような種類の消去を検討します。 Javaがいることを許可された場合、それはポスト消去を行うことができる最高は

new Object[4] 

ほとんどtoArray実装がClassとして渡された型ヒント与えられた権利タイプの出力配列を構築するためにjava.lang.reflect.Arrayを使用しています。

+0

ありがとうございましたMike、私はこのメソッドT [] toArray(T [] arg0)に気付かなかった - それは必要なものを返す。 – justadreamer

+9

を使用するか、サイズ0の配列の割り当てを避けたい場合は 'toArray(new String [list.size()])'を使用してください。 –

+0

@ratchetfreak、ありがとう。プレサイズについて編集しました。 –

12

配列は、ジェネリック医薬品のみのJava 5で導入され、ジェネリック医薬品が存在する前List.toArray()メソッドは、Javaの1.2で導入されたが、初めからJavaでてきた、そしてそれはObject[]を返すように指定されたため。多くの既存のコードではList.toArray()Object[]を返すと予想されているので、今すぐ変更することはできません。

さらに、実行時にジェネリックが消去されるため、ArrayListは、必要な場合に適切な型の配列を構築することさえできませんでした。

これの抜け穴はList.toArray(T[])メソッドです。正しいタイプの配列を返します。正しいタイプの配列を指定すると、使用するタイプを知ることができます。

+1

"であり、Object []を返すように指定されていました。既存のコードの多くは、List.toArray()がObject []を返すことを期待しているので、今すぐ変更することはできません。ナンセンス。ジェネリックのためにJavaコレクションメソッドの戻り値の型が変更されました。これは完全に無関係です。実際の理由は、さまざまな型の配列が実行時に異なるため、おそらく適切な型の配列を返すことができないということです。これはジェネリックの前と後の両方に当てはまります。 – newacct

+0

ダニエル、真剣に?この質問は何回何度尋ねられましたか? 100万?そしてあなたは重複した質問に答えて私に講演していましたか? – irreputable

+0

@irreputable:私は昨日これに答えるとすぐに正確な複製を見ることはできませんでした。クイック検索は今日私が思った[これは](http://stackoverflow.com/questions/6173495/why-does-javas-collectione-toarray-return-an-object-rather-than-an-e)になった十分に近いです。質問が重複していると確信している場合は、悪意を持って考えるのではなく、あなた自身を閉めるために投票するだけではいかがですか?あなたは十分な担当者を持っています。 –

3

その理由を理解するには、Collection.toArray()のjavadocを見てから、Collection.toArray(T[] a)メソッドを見てください。また、Javaのジェネリックは実行時に消去されることに注意してください。

1

理由は2つである:

  1. 方法は、ジェネリックの前、彼らは後方互換性を壊すことなく、署名を変更することができませんでした。いずれの場合においても

  2. ListClass<T>なしで構成されているように、実装はタイプTのアレイを構築するための方法はありません。

+0

あなたはどのように署名を変更しますか?もちろん、T []への@newacct – newacct

+0

。 Downvoterは説明してください。 – EJP

+0

あなたは返品タイプT []を意味しますか?メソッドシグネチャを変更したときに、実装が一致するように実装を変更することが慣例であるため、メソッドがまだObject [] – newacct

1

回避策を使用するようになります。

 List<String> list = new ArrayList<>(); 
     list.add("Sputnik"); 
     list.add("Explorer"); 

     //String[] str = list.toArray(); 

これがスローするようにバインドされている:互換性のない型:オブジェクトが[]の文字列に変換することはできません[]エラー

 Instead use: 

     String[] str = list.toArray(new String[0]); 
     or 
     String[] str = list.toArray(new String[list.size()]); 
関連する問題