Javaジェネリックを配列に含めることができないのはなぜですか?


10

ArrayListの配列を作成しようとすると、なぜArrayList<Integer>[] arr=new ArrayList<Integer>[40];エラーが発生し、Javaはこれを許可しないのですか?

ジェネリックのJavaの実装、任意の言語のジェネリック、または任意の何かに関連する理由はありますか?


回答:


20

これはJavaのジェネリックスの主要な穴の1つです。配列は共変です。つまり、型の配列Foo[]Object[]andのサブクラスですParentOfFoo[]。これとList<Foo>は異なり、この動作はありません。

これは、Javaにジェネリックがなかった場合(Java 5まで)に重要でした。

ただし、実行時に配列がどの型であるかを知りたいというこのトリッキーな問題があります。ただし、Javaのジェネリックスは型消去に基づいています。これらの2つはうまくメッシュ化されず、そこで問題が発生します。

つまり、Java 1では、共変配列がジェネリックの欠如によって生じた穴を部分的に埋めていました。ただし、この穴を適切に埋めようとしたときに、下位互換性のために配列を実装することはかなり不可能でした。

実際、ジェネリックのフレームワークを実際に作成した人であるMartin Oderskyは、なぜScalaを作ったのかについてのインタビューで、これについてここで話しました。(Scalaの歴史にまったく興味があるなら、かなり魅力的です)


3

ジェネリックのJavaの実装、任意の言語のジェネリック、または任意の何かに関連する理由はありますか?

実際、それはやや恣意的です。

問題は、型システムに穴を開けることができることです。これは、ArrayList<T>[]にキャストObject[]できArrayList<U>、配列にを配置できるためU != Tです。

Java設計者たちは、このホールをまったく許可new ArrayList<T>[N]しないことで、できる限り積極的にこの穴を塞ぐことにしました。

ただし、ジェネリックの配列のアップキャストを許可しないことでプラグインされている可能性もあります(「チェックされていない」警告なし)。


この答えは過小評価されています。非常にシンプルで、あいまいな用語で専門用語を使用しません。どうもありがとう。
Tung Nguyen

これは、あなたが入れた場合とは異なっているなぜあなたは上の手の込んだしたい場合がありますIntegerObject[]実際だString[]
Caleth

-3

これは、配列が共変であり、すべての型がオブジェクトのサブクラスであるため、キャスト例外が原因で実行時にエラーが発生するためです。一方、ジェネリックは不変である、それはタイプに基づいていますので、とき確保やタイプセーフなので、それはコンパイラエラーを与える入力し作成しないように入力した場合。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.