Java のダイヤモンド演算子 (<>) の目的は何ですか? 質問する

Java のダイヤモンド演算子 (<>) の目的は何ですか? 質問する

Java 7 のダイヤモンド演算子を使用すると、次のようなコードが可能になります。

List<String> list = new LinkedList<>();

しかし、Java 5/6 では、次のように簡単に記述できます。

List<String> list = new LinkedList();

型消去についての私の理解では、これらはまったく同じです。(いずれにしても、ジェネリックは実行時に削除されます)。

そもそもなぜダイヤモンドにこだわるのでしょうか? ダイヤモンドによって、どのような新しい機能や型安全性が可能になりますか? 新しい機能が得られないのであれば、なぜそれを機能として言及するのでしょうか? この概念に対する私の理解は間違っているのでしょうか?

ベストアンサー1

問題は

List<String> list = new LinkedList();

左側ではジェネリック型を使用しておりList<String>、右側ではraw型を使用していますLinkedList。Java の raw 型は、ジェネリック以前のコードとの互換性のためだけに存在しており、絶対に必要な場合を除き、新しいコードでは決して使用しないでください。

さて、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);

ジェネリックは、間違った処理が行われないようにコンパイル時に保護するために存在します。上記の例では、raw 型を使用するとこの保護が得られず、実行時にエラーが発生します。これが、raw 型を使用すべきでない理由です。

// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);

ただし、ダイヤモンド演算子を使用すると、割り当ての右側を左側と同じ型パラメータを持つ真のジェネリック インスタンスとして定義できます。パラメータを再度入力する必要はありません。これにより、生の型を使用する場合とほぼ同じ労力でジェネリックの安全性を維持できます。

理解しておくべき重要なことは、生の型 ( なし<>) はジェネリック型と同じようには扱えないということだと思います。生の型を宣言すると、ジェネリックの利点や型チェックは一切得られません。ジェネリックは Java 言語の汎用的な部分であることも覚えておく必要があります。ジェネリックは の引数なしのコンストラクターにのみ適用されるのではありませんCollection

おすすめ記事