1. 序章

この簡単なチュートリアルでは、生の型、それらが何であるか、そしてなぜそれらを避けるべきなのかを見ていきます。

2. 生のタイプ

raw型は、一般的なインターフェイスまたはクラスの名前であり、型引数はありません:

List list = new ArrayList(); // raw type

それ以外の:

List<Integer> listIntgrs = new ArrayList<>(); // parameterized type

リストパラメータ化されたタイプインターフェースのリストその間リスト生タイプインターフェースのリスト

生の型は、一般的でないレガシーコードとインターフェイスするときに役立ちます。

それ以外の場合は、お勧めしません。これは次の理由によるものです。

  1. 彼らは表現力がありません
  2. 彼らは型安全性を欠いており、
  3. 問題は、コンパイル時ではなく実行時に観察されます

3. 表現力のない

raw型は、パラメーター化された型と同じように文書化および説明しません。

パラメータ化されたタイプは簡単に推測できますリストを含むリストです s。 ただし、raw型にはこの明確さが欠けているため、raw型とそのAPIメソッドを操作するのは困難です。

これをよりよく理解するために、 Listインターフェイスのメソッドget(int index)のシグネチャを見てみましょう。

/**
 * Returns the element at the specified position in this list.
 *
 * @param index index of the element to return
 * @return the element at the specified position in this list
 * @throws IndexOutOfBoundsException if the index is out of range
 *         (<tt>index < 0 || index >= size()</tt>)
 */
E get(int index);

方法 get(int index) を返します位置で索引パラメータ化されたタイプリスト

ただし、rawタイプ List の場合、Objectを返します。 したがって、生の型リストの要素の型を検査および識別し、適切な型キャストを追加するために余分な労力を費やす必要があります。これにより、実行時にバグが発生する可能性があります。 rawタイプはタイプセーフではありません

4. タイプセーフではない

生の型でジェネリック前の振る舞いを取得します。 したがって、raw型 ListObjectを受け入れ、は任意のデータ型の要素を保持できます。 これは、パラメーター化されたタイプとrawタイプを混合するときに、タイプの安全性の問題につながる可能性があります。

インスタンス化するコードを作成して、これを見てみましょう。 リスト生の型を受け入れるメソッドに渡す前にリストと追加します整数それに:

public void methodA() {
    List<String> parameterizedList = new ArrayList<>();
    parameterizedList.add("Hello Folks");
    methodB(parameterizedList);
}

public void methodB(List rawList) { // raw type!
    rawList.add(1);
}

コードは(警告付きで)コンパイルされ、Integerは実行時にraw型Listに追加されます。 The リストそれは引数として渡されました文字列と整数が含まれるようになりました。

コンパイラは、raw型を使用しているため、警告を出力します。

Note: RawTypeDemo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

5. 実行時の問題

生の型の型安全性の欠如は、実行時に例外を引き起こす可能性のある因果関係を持っています。

前の例を次のように変更してみましょう methodA のインデックス位置1にある要素を取得しますリスト電話した後 methodB

public void methodA() {
    List<String> parameterizedList = new ArrayList<>();
    parameterizedList.add("Hello Folks");
    methodB(parameterizedList);
    String s = parameterizedList.get(1);
}

public void methodB(List rawList) {
    rawList.add(1);
}

コードは(同じ警告で)コンパイルされ、実行されるとClassCastExceptionをスローします。 これは、メソッド get(int index) Integer を返すときに発生します。これは、タイプStringの変数に割り当てることはできません。

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

6. 結論

生の型は扱いにくく、コードにバグをもたらす可能性があります。

それらを使用すると、悲惨な結果を招く可能性があります。残念ながら、これらの災害のほとんどは実行時に発生します。

このチュートリアルのすべてのスニペットをGitHubで確認してください。