13

List<String> list = new ArrayList();コンパイラの警告が発生します。

ただし、次の例は警告なしでコンパイルされます。List<String> list = new ArrayList<>();

なぜダイヤモンド演算子の導入が必要なのか、興味があります。型引数が存在しない場合、コンストラクターで型推論を行わないのはなぜですか (Java の静的メソッドに対して既に行われ、Google guava などのコレクション ライブラリによって悪用されているため)。

編集:ミリムースの回答を出発点として使用して、実際に型消去が何であるかを調べましたが、すべての型情報を削除するだけではありません。コンパイラは実際にはもう少し多くのことを行います(公式ドキュメントからコピー):

  • ジェネリック型のすべての型パラメーターをそれらの境界またはオブジェクト (型パラメーターが無制限の場合) に置き換えます。したがって、生成されたバイトコードには、通常のクラス、インターフェース、およびメソッドのみが含まれます。
  • 型の安全性を維持するために、必要に応じて型キャストを挿入します。
  • 拡張されたジェネリック型でポリモーフィズムを保持するブリッジ メソッドを生成します。
4

6 に答える 6

7

Java 開発者は、既存のプログラムの動作を変更しないように懸命に努力しています。List<String> list = new ArrayList();コンパイルし、生の ArrayList を作成します。型推論が適用された場合、結果は になり、ArrayList<String>動作が変化し、プログラムの他の場所で実行時エラーが発生する可能性があります。

================================================== ==========================

さらなる検討と @millimoose によるコメントの後、動作の変更は初期化子に対してローカルであり、コンパイル時に検出されることがわかりました。次のプログラムを検討してください。

import java.util.ArrayList;
import java.util.List;


public class Test {
  public static void main(String[] args) throws Exception {
    List<Integer> integers = new ArrayList<Integer>();
    integers.add(Integer.valueOf(3));
    integers.add(Integer.valueOf(4));
    List<String> list = new ArrayList(integers);
    System.out.println(list);
  }
}

整数参照を含む[3, 4]a の望ましくない状況にもかかわらず、型推論がなければ、 を実行して出力します。List<String>

型推論では、を作成するときに を引数としてArrayList(Collection<? extends E> c)使用できないため、コンパイルされません。List<Integer>ArrayList<String>

于 2013-02-16T11:46:57.460 に答える
7

決定的な答えは、その機能を設計した人から得なければなりませんが、互換性のためにコンパイラにまったく別のことをさせる生の型の使用とこれを区別することだと思います。生の型を含む式は、ジェネリックを含む式とは微妙に異なる方法で処理されます。例は、この SO の質問にあります:ジェネリックが無関係なコレクションを台無しにする

于 2013-02-16T11:48:36.763 に答える
5

Java 5 および 6 のコンパイラが必要とする完全な構文は次のとおりです。

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

彼らは私たちのために構文を簡素化し、代入演算子の両側に同じ型パラメーターを記述しないようにすることにしました。ただし、<>オペレーターは、ユーザーが何をしているのかを確実に理解する必要があります。書くnew ArrayList<>()ことで、「ジェネリック型のインスタンスを作成していることを理解し、ジェネリックパラメーターは割り当ての左側で宣言したものと同じです」と言います。

于 2013-02-16T11:47:05.697 に答える
3

これは、Java 7 のJava Genericsの改善の一部です。

final List<String> list = new ArrayList<String>();

今、あなたは書くことができます

final List<String> list = new ArrayList<>();

これは同等です-コンパイラーがそれを解決します。これは同じではありません

final List list = new ArrayList();

これは型なしListです。

于 2013-02-16T11:46:24.917 に答える