Java汎用を再確認し、より深く理解し、よりよく使用することができます!
6945 ワード
1.引用
jdk5.0にJava汎用が導入され、エラーを低減し、タイプに追加の抽象層を追加することを目的としています.Javaの汎用性、汎用性の背後にあるターゲット、および汎用性を使用してコードの品質を向上させる方法について簡単に説明します.
2.なぜ汎用型を使うのですか.
JavaでIntegerを格納するリストを作成するシーンを想定します.コードは次のように書かれる可能性があります.
驚くべきことに、コンパイラは最後の行を提示します.返されるデータ型がわかりません.したがって、コンパイラのプロンプトには、明示的な変換が必要です.
リストの戻りタイプが整数であることを保証する約束はありません.定義されたリストには、任意のオブジェクトを含めることができます.コンテキストをチェックしてリストを取得したことしか知りません.タイプを表示する場合は、Objectのみが保証されるため、タイプが安全であることを確認するために明示的な変換が必要です.
この変換はうるさいかもしれませんが、このリストのデータ型が整数であることを知っています.変換すると、私たちのコードもめちゃくちゃになります.プログラマが明示的な変換でエラーを発生した場合、タイプに関連するランタイムエラーが投げ出される可能性があります.
プログラマが特定のタイプを使用する意図を表現し、コンパイラがこのタイプの正確性を確保できれば、これはより容易になります.
これが汎用型の背後にある核心思想である.
前のコード・セグメントの最初の行を次のように変更します.
タイプを含む菱形演算子<>を追加することで、このリストの特化範囲をIntegerタイプに縮小します.つまり、リストに保存するタイプを指定します.コンパイラは、コンパイル時にこのタイプを強制的に実行できます.
小さなプログラムでは、これはわずかな追加のように見えます.しかし、より大きなプログラムでは、顕著な頑丈性を増加させ、プログラムをより読みやすくすることができる.
3.汎用方法
汎用メソッドは、単一のメソッドで記述を宣言するメソッドであり、異なるタイプのパラメータで呼び出すことができます.コンパイラは、使用するタイプの正確性を確保します.以下に、汎用メソッドのいくつかのプロパティを示します.汎用メソッドメソッド宣言の戻りタイプの前に、タイプパラメータ(ラップタイプの菱形演算子) があります.型パラメータは、境界を有することができる(境界は、本明細書で後述する) 汎用メソッドは、メソッド署名において をカンマで区切る異なるタイプのパラメータを有することができる.汎用法の方法体は一般法と同様 である.
配列をリストに変換する汎用メソッドの例を定義します.
前の例では、方法宣言の
T型要素を持つ配列をG型要素を含むリストに変換する関数を渡しています.たとえば、IntegerをString表現に変換します.
Oracleでは、汎用タイプを大文字で表すことを推奨し、JavaコレクションでTがタイプ、Kがキー、Vが値を表すなど、より記述的なアルファベットを選択して形式タイプを表すことを推奨します.
3.1.はんけいきょうかい
前述したように、タイプパラメータは境界付きであってもよい.境界は「制限」を意味し、メソッドが許容できるタイプを制限することができます.
たとえば、メソッドがタイプとそのすべてのサブクラス(上限)を受け入れるか、タイプがすべてのスーパークラス(下限)を受け入れるかを指定できます.
上界タイプを宣言するには、タイプの後にキーワードextendsを使用し、使用する上限に従います.例:
ここではキーワードextendsを用いてタイプT拡張クラスの上限を表したり,インタフェースの上限を実現したりする.
3.2. 複数の境界
タイプには、次のように複数の上界があります.
T拡張タイプの1つがクラス(すなわちNumber)である場合、境界リストの1番目に配置する必要があります.そうしないと、コンパイル時にエラーが発生します.
4.ワイルドカードの使用
ワイルドカードはJavaで疑問符「?」で表され、未知のタイプを指すために使用されます.ワイルドカードは汎用を使用する場合に特に役立ち、パラメータタイプとして使用できますが、まず重要な注釈です.
ObjectはすべてのJavaクラスのスーパータイプであることはよく知られていますが、Objectの集合は任意の集合のスーパータイプではありません.(ちょっと回り道かもしれませんが、みんなよく細かくしてください)
たとえば、
jdk5.0にJava汎用が導入され、エラーを低減し、タイプに追加の抽象層を追加することを目的としています.Javaの汎用性、汎用性の背後にあるターゲット、および汎用性を使用してコードの品質を向上させる方法について簡単に説明します.
2.なぜ汎用型を使うのですか.
JavaでIntegerを格納するリストを作成するシーンを想定します.コードは次のように書かれる可能性があります.
List list = new LinkedList();
list.add(new Integer(1));
Integer i = list.iterator().next();
驚くべきことに、コンパイラは最後の行を提示します.返されるデータ型がわかりません.したがって、コンパイラのプロンプトには、明示的な変換が必要です.
Integer i = (Integer) list.iterator.next();
リストの戻りタイプが整数であることを保証する約束はありません.定義されたリストには、任意のオブジェクトを含めることができます.コンテキストをチェックしてリストを取得したことしか知りません.タイプを表示する場合は、Objectのみが保証されるため、タイプが安全であることを確認するために明示的な変換が必要です.
この変換はうるさいかもしれませんが、このリストのデータ型が整数であることを知っています.変換すると、私たちのコードもめちゃくちゃになります.プログラマが明示的な変換でエラーを発生した場合、タイプに関連するランタイムエラーが投げ出される可能性があります.
プログラマが特定のタイプを使用する意図を表現し、コンパイラがこのタイプの正確性を確保できれば、これはより容易になります.
これが汎用型の背後にある核心思想である.
前のコード・セグメントの最初の行を次のように変更します.
List list = new LinkedList<>();
タイプを含む菱形演算子<>を追加することで、このリストの特化範囲をIntegerタイプに縮小します.つまり、リストに保存するタイプを指定します.コンパイラは、コンパイル時にこのタイプを強制的に実行できます.
小さなプログラムでは、これはわずかな追加のように見えます.しかし、より大きなプログラムでは、顕著な頑丈性を増加させ、プログラムをより読みやすくすることができる.
3.汎用方法
汎用メソッドは、単一のメソッドで記述を宣言するメソッドであり、異なるタイプのパラメータで呼び出すことができます.コンパイラは、使用するタイプの正確性を確保します.以下に、汎用メソッドのいくつかのプロパティを示します.
配列をリストに変換する汎用メソッドの例を定義します.
public List fromArrayToList(T[] a) {
return Arrays.stream(a).collect(Collectors.toList());
}
前の例では、方法宣言の
は、この方法が汎用タイプTを処理することを示す.メソッドがvoidを返しても、そうする必要があります.上記のように、メソッドは複数の汎用タイプを処理することができ、この場合、すべての汎用タイプをメソッド宣言に追加する必要があります.たとえば、上記のメソッドを変更してタイプTとタイプGを処理する場合は、次のように書く必要があります.public static List fromArrayToList(T[] a, Function mapperFunction) {
return Arrays.stream(a)
.map(mapperFunction)
.collect(Collectors.toList());
}
T型要素を持つ配列をG型要素を含むリストに変換する関数を渡しています.たとえば、IntegerをString表現に変換します.
@Test
public void givenArrayOfIntegers_thanListOfStringReturnedOK() {
Integer[] intArray = {1, 2, 3, 4, 5};
List stringList
= Generics.fromArrayToList(intArray, Object::toString);
assertThat(stringList, hasItems("1", "2", "3", "4", "5"));
}
Oracleでは、汎用タイプを大文字で表すことを推奨し、JavaコレクションでTがタイプ、Kがキー、Vが値を表すなど、より記述的なアルファベットを選択して形式タイプを表すことを推奨します.
3.1.はんけいきょうかい
前述したように、タイプパラメータは境界付きであってもよい.境界は「制限」を意味し、メソッドが許容できるタイプを制限することができます.
たとえば、メソッドがタイプとそのすべてのサブクラス(上限)を受け入れるか、タイプがすべてのスーパークラス(下限)を受け入れるかを指定できます.
上界タイプを宣言するには、タイプの後にキーワードextendsを使用し、使用する上限に従います.例:
public List fromArrayToList(T[] a) {
...
}
ここではキーワードextendsを用いてタイプT拡張クラスの上限を表したり,インタフェースの上限を実現したりする.
3.2. 複数の境界
タイプには、次のように複数の上界があります.
T拡張タイプの1つがクラス(すなわちNumber)である場合、境界リストの1番目に配置する必要があります.そうしないと、コンパイル時にエラーが発生します.
4.ワイルドカードの使用
ワイルドカードはJavaで疑問符「?」で表され、未知のタイプを指すために使用されます.ワイルドカードは汎用を使用する場合に特に役立ち、パラメータタイプとして使用できますが、まず重要な注釈です.
ObjectはすべてのJavaクラスのスーパータイプであることはよく知られていますが、Objectの集合は任意の集合のスーパータイプではありません.(ちょっと回り道かもしれませんが、みんなよく細かくしてください)
たとえば、
List