188

Joshua Bloch 著『Effective Java』より、

  1. 配列は、2 つの重要な点でジェネリック型と異なります。最初の配列は共変です。ジェネリックは不変です。
  2. 共変とは、単に X が Y のサブタイプである場合、X[] も Y[] のサブタイプになることを意味します。文字列はオブジェクトのサブタイプであるため、配列は共変です。

    String[] is subtype of Object[]

    不変とは、単に X が Y のサブタイプであるかどうかに関係なく、

     List<X> will not be subType of List<Y>.
    

私の質問は、Java で配列を共変にするという決定がなぜなのかということです。Why are Arrays invariant, but Lists covariant?などの他の SO 投稿があります。、しかし、彼らはScalaに焦点を当てているようで、私は従うことができません.

4

9 に答える 9

3

パラメトリック型の重要な機能は、多相アルゴリズム、つまり などのパラメータ値に関係なくデータ構造を操作するアルゴリズムを記述できることArrays.sort()です。

ジェネリックでは、それはワイルドカード型で行われます:

<E extends Comparable<E>> void sort(E[]);

ワイルドカード型を本当に便利にするには、ワイルドカード キャプチャが必要であり、それには型パラメーターの概念が必要です。配列が Java に追加された時点では、そのどれも利用できませんでした。参照型共変の配列を作成することで、ポリモーフィック アルゴリズムを許可するはるかに簡単な方法が可能になりました。

void sort(Comparable[]);

ただし、その単純さは静的型システムに抜け穴を開けました。

String[] strings = {"hello"};
Object[] objects = strings;
objects[0] = 1; // throws ArrayStoreException

参照型の配列へのすべての書き込みアクセスの実行時チェックが必要です。

一言で言えば、ジェネリックによって具現化された新しいアプローチは、型システムをより複雑にしますが、静的に型安全でもありますが、古いアプローチはより単純で、静的に型安全ではありません。言語の設計者は、ほとんど問題を引き起こさない型システムの小さな抜け穴を閉じるよりも、もっと重要なことを行うという、より単純なアプローチを選択しました。その後、Java が確立され、差し迫ったニーズが処理されたとき、彼らはジェネリックに対して適切にそれを行うためのリソースを持っていました (ただし、配列に対してそれを変更すると、既存の Java プログラムが機能しなくなります)。

于 2013-09-13T17:48:27.400 に答える
3

配列を共変にした最初の場所で、彼らは間違った決定をしたと思います。hereで説明されているように、型の安全性が損なわれ、下位互換性のためにそれで行き詰まり、その後、ジェネリックに対して同じ間違いを犯さないようにしました。これが、 Joshua Blochが本「Effective Java(second edition)」の項目 25 で配列よりもリストを好む理由の 1 つです。

于 2016-04-01T19:22:08.683 に答える
2

ジェネリックは不変です: JSL 4.10から:

...サブタイプはジェネリック型には拡張されません: T <: U はC<T><: C<U>...を意味しません。

さらに数行、JLS は
配列が共変であることも説明しています(最初の箇条書き):

4.10.3 配列型間のサブタイプ

ここに画像の説明を入力

于 2014-06-15T17:37:10.647 に答える
1

私の見解: コードが配列 A[] を想定していて、B[] を指定した場合、B は A のサブクラスである場合、心配することは 2 つだけです。それ。そのため、すべてのケースで型の安全性が確保されるように言語規則を作成することは難しくありません (主な規則はArrayStoreException、A を B[] に挿入しようとすると an がスローされる可能性があるということです)。ただし、ジェネリックの場合、クラスを宣言するとき、クラスの本体で使用されるSomeClass<T>方法Tはいくつでもある可能性があり、可能性のあるすべての組み合わせを考え出していつクラスを作成するかについてのルールを書くのは複雑すぎると思います物事が許可されているときと許可されていないとき。

于 2013-09-06T21:56:39.543 に答える