Java のジェネリックに関するもう 1 つの非常に基本的な質問は、私の以前の質問から直接続きます。以下のコードを書くことで、コンパイラに同じ情報を 2 回提供していませんか。左側と右側の両方を提供する必要があるのはなぜですか?
List<Number> numbers = new ArrayList<Number>();
編集:いくつかの回答でわかるように、Java 7以降では不要になりました。しかし、Java 7 より前にそれができなかった理由を知りたいですか?
Java のジェネリックに関するもう 1 つの非常に基本的な質問は、私の以前の質問から直接続きます。以下のコードを書くことで、コンパイラに同じ情報を 2 回提供していませんか。左側と右側の両方を提供する必要があるのはなぜですか?
List<Number> numbers = new ArrayList<Number>();
編集:いくつかの回答でわかるように、Java 7以降では不要になりました。しかし、Java 7 より前にそれができなかった理由を知りたいですか?
この冗長な情報を削除するダイヤモンド演算子が導入されています。
このSOリンクも参照してくださいJava 7のダイヤモンド演算子のポイントは何ですか?
私の読書/理解から、ジェネリックがJavaでうまく行われたとは思いません。? 最後に導入されたオペレーターは、扱いが面倒です。消去があるという事実は、私の意見ではそれが靴べらだったことを示しています。それは仕事をしますが、私はそれがはるかに良いと思います
Java 7 より前では、コンストラクターのジェネリック型推論がサポートされていないためです。これは、ダイヤモンド演算子によって Java 7 で解決されています。
次のような回避策として、ジェネリック ファクトリ メソッドを記述することもできます。
public static <T> List<T> createArrayList() {
return new ArrayList<T>();
}
それから
List<Integer> list = createArrayList();
これは疑わしいですが、機能します。そして、Maps やその他の複数引数のジェネリック型に対しては、おそらく十分な成果が得られるでしょう。
編集へ:言語設計者は、型消去を伴うジェネリックを実装したため、ジェネリック型推論をサポートしないことにしたのかもしれません。別の疑わしい決定だと思います...そうでなければ、以前のJavaバージョンでこの機能に対して重大な理由があるとは思わないでください。(そして、Peter Lawrey の補遺によると、それはまだ存在していません。)
1 つはリファレンスであり、もう 1 つは実装であるためです。行の左側は、インスタンス化された変数を格納する参照を設定しています。Java は「ランタイム型消去」を使用して Generics を実装するため、参照割り当て以外のコードで Generic パラメータが何であったかを知る方法はありません。割り当てられます。
編集-J7の変更について知りませんでした(私は少し時代遅れです:))-彼らはこの問題を解決したようです。
他の回答で説明されている理由と同様に、この例の右側の引数は左側の引数とまったく同じである必要はありません。例:
List<? extends Calendar> cals = new ArrayList<GregorianCalendar>();