1. ホーム
  2. java

[解決済み] Javaにおける菱形演算子(<>)のポイントは何ですか?

2022-03-21 07:16:10

質問

java 7のdiamond演算子では、以下のようなコードが可能です。

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

しかし、Java 5/6では、単純に書くことができる。

List<String> list = new LinkedList();

私の型消しの理解では、これらは全く同じものです。(ジェネリックはとにかく実行時に削除される)。

なぜわざわざダイヤモンドを使うのか?それによってどんな新しい機能、型安全性が実現されるのでしょうか?もし、新しい機能をもたらさないのであれば、なぜそれを機能として言及するのでしょうか?私のこのコンセプトの理解に誤りがあるのでしょうか?

解決方法は?

の問題は

List<String> list = new LinkedList();

は、左側で ジェネリック タイプ List<String> ここで、右側では タイプ LinkedList . Javaにおける生の型は、事実上、ジェネリック以前のコードとの互換性のためにのみ存在し、新しいコードでは、以下の場合を除いて決して使用すべきではありません。 を使用する必要があります。

さて、Javaに最初からジェネリクスがあり、型がなかったとしたら、たとえば LinkedList ジェネリック型のコンストラクタは、可能であれば代入の左辺から型パラメータを自動的に推論するようにできたはずです。しかし、そうしなかったために、後方互換性のために生の型とジェネリック型を別個に扱わなければならなくなった。そのため、彼らは 若干異なる しかし、同じように便利なのが、汎用オブジェクトの新しいインスタンスを、その型パラメータを繰り返すことなく宣言する方法、つまりdiamond演算子です。

元の例である 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);

しかし、diamond演算子を使えば、右辺の代入を左辺と同じ型パラメータを持つ真のジェネリックインスタンスとして定義することができます...それらのパラメータを再度タイプする必要はありません。これにより、ジェネリックインスタンスの安全性を ほとんど 生の型を使用するのと同じ労力です。

理解すべき重要な点は、生の型( <> は、汎用型と同じようには扱えません。生の型を宣言した場合、ジェネリックの利点や型チェックは何も得られません。また ジェネリックは、Java言語の汎用的な部分です。 の引数なしコンストラクタだけに適用されるわけではありません。 Collection s!