パスワードを忘れた? アカウント作成
497968 journal

quabbinの日記: Genericsとjava.util.Collection#toArray()

日記 by quabbin

JavaのGenericsは面白いが、ちょっと凝ったことをすると実装に戸惑う。

たとえばjava.util.Collectionの#toArray()。
実際のJDKではtoArrayは
        Object[] toArray();
として実装されている。
Collectionインターフェースは
        interface Collection
と宣言されているので、toArrayはGenericで指定されている型変数Eに対して
          E[] toArray();
として欲しいものだろう。
実際調べてみると、そのような間違いをしているblogを見かけたりもした。
引数を取る
        Object[] toArray(Object[] a); // J2SE 1.4
のほうは、
          T[] toArray(T[] a); // J2SE 5.0
となり、String[] array = list.toArray(new String[list.size()]);のような実装ができるにもかかわらず。

なぜそのようなAPIが用意されていないのだろう。
実際のところ論議を読んでいないのでわからないが、多分にこの現象は考慮済みであろう。
#toArray()は#toArray(T[])に対し、引数をもたないために自分でArrayを作成せねばならない。
まず仕様として、#toArrayは返却する配列のComponentTypeを取得する手段として、どうしてもclass宣言の場所にある型変数Eを使わねばならないが、これは引数の型を正とするべく実装が素直であろう#toArray(T[])と、同じ名前なのに振る舞いが変わってしまい、美しくないと結論付けたのではないだろうか。
次に実装上として、多分に型変数Eに対してEのClassオブジェクトを取得するAPIがないこと問題となろう。なぜそういうAPIなり構文なりを用意しなかったかは別の問題として。

よって、#toArray()は文脈上はキャスト不要としてほしいのに、キャスト不要とならずに戸惑うこととなる。
どうしてあげればいいのだろうか…。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

未知のハックに一心不乱に取り組んだ結果、私は自然の法則を変えてしまった -- あるハッカー

読み込み中...