raw-types-java
Javaの生の型
1. 前書き
このクイックチュートリアルでは、生の型、それらが何であるのか、なぜそれらを避けるべきなのかを見ていきます。
2. 生のタイプ
生の型は、*型引数のない*汎用インターフェースまたはクラスの名前です*
List list = new ArrayList(); // raw type
の代わりに:
List<Integer> listIntgrs = new ArrayList<>(); // parameterized type
_List <Integer> _は_List <E> _インターフェイスの_parameterized type_であり、_List_は_List <E> _インターフェイスの_raw type_です。
生の型は、非ジェネリックのレガシーコードとインターフェースするときに役立ちます。
それ以外の場合、しかし、それはお勧めできません。
-
彼らは表情豊かではありません
-
型の安全性に欠け、そして
-
問題はコンパイル時ではなく実行時に観察されます
3. 表現力に欠ける
生の型は、パラメータ化された型の方法を文書化せず、説明しません。
パラメータ化された型_List <String> _は__String__sを含むリストであると簡単に推測できます。 ただし、未加工の型にはこの明快さが欠けているため、その型およびその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)_は、パラメーター化された型_List <String> _の位置_index_にある_String_を返します。
ただし、未加工のタイプ_List_の場合は、_Object_を返します。 したがって、生のタイプ_List_の要素のタイプを検査および特定し、*適切なタイプキャストを追加するために余分な努力をする必要があります。
4. タイプセーフではありません
未加工の型を使用して、ジェネリック前の動作を取得します。 したがって、生の_List_型は_Object_を受け入れ、*任意のデータ型の要素を保持できます*。 これは、パラメーター化された型と生の型を混在させると、型の安全性の問題につながる可能性があります。
_List <String> _をインスタンス化するコードを作成してから、未加工のタイプ_List_を受け入れて_Integer_を追加するメソッドに渡すことで、これを見てみましょう。
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_に追加されます。 引数として渡された_List <String> _には、現在_String_と_Integer_が含まれています。*
コンパイラーは、生の型を使用しているため、警告を出力します。
Note: RawTypeDemo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
5. 実行時の問題
生の型に対する型安全性の欠如は、実行時に例外を引き起こす可能性のある因果効果を持っています。
前の例を変更して、_methodB_を呼び出した後、_methodA_が_List <String> _のインデックス位置1にある要素を取得するようにします。
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. 結論
生の型は扱いが難しく、コードにバグを引き起こす可能性があります。
それらを使用すると、悲惨な結果を招く可能性があり、残念ながら、これらの災害のほとんどは実行時に発生します。
このチュートリアルのすべてのスニペットhttps://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-lang-oop-2[GitHubで]をご覧ください。