の問題
List<String> list = new LinkedList();
左側ではジェネリック型を使用List<String>
していますが、右側では生の型を使用していますLinkedList
。Java の生の型は、事実上、ジェネリック前のコードとの互換性のためにのみ存在し、絶対に必要な場合を除き、新しいコードでは決して使用しないでください。
ここで、Java が最初からジェネリックを持っていて、ジェネリックを持つLinkedList
前に最初に作成された などの型を持っていなかった場合、ジェネリック型のコンストラクターがその型パラメーターを左から自動的に推論するようにすることができたはずです。 -可能であれば、割り当ての側を渡します。しかし、そうではなく、下位互換性のために生の型とジェネリック型を異なる方法で処理する必要があります。そのため、型パラメータを繰り返さずにジェネリック オブジェクトの新しいインスタンスを宣言する、わずかに異なるが同様に便利な方法を作成する必要があります... ダイヤモンド演算子です。
の元の例に関する限りList<String> list = new LinkedList()
、コンパイラはその割り当てに対して警告を生成する必要があるためです。このことを考慮:
List<String> strings = ... // some list that contains some strings
// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);
ジェネリックは、間違ったことを行うことに対するコンパイル時の保護を提供するために存在します。上記の例では、生の型を使用すると、この保護が得られず、実行時にエラーが発生します。これが生の型を使用すべきでない理由です。
// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);
ただし、ひし形演算子を使用すると、割り当ての右側を、左側と同じ型パラメーターを持つ真のジェネリック インスタンスとして定義できます。これらのパラメーターを再度入力する必要はありません。raw 型を使用するのとほぼ同じ労力で、ジェネリックの安全性を維持できます。
理解すべき重要なことは、生の型 ( なし<>
) はジェネリック型と同じように扱うことができないということです。生の型を宣言すると、ジェネリックの利点と型チェックがまったく得られません。また、ジェネリクスは Java 言語の汎用的な部分であることも覚えておく必要があります。ジェネリクスは s の引数なしのコンストラクタだけに適用されるわけではありませんCollection
!