前回はジェネリックを使ったクラスの基本を学んだ。今回はジェネリックを使ったメソッドの理解を深めよう。
お題
今回は、配列の先頭要素を返す getFirst() メソッドを作成する。
ただし、文字列専用や整数専用ではなく、さまざまな型の配列に対応できるようにしたい。
考察
まずはObject型を使ったメソッドを作成してみよう。
public static Object getFirst(Object[] array) {
return array[0];
}使用例
String name = (String) getFirst(names);
Integer num = (Integer) getFirst(numbers);確かにこれで目的は達成されている。ただし、
- 毎回キャストが必要
- 間違った型にキャストしてもコンパイル時には気付けない
といった問題がある。
ジェネリックメソッド
それではジェネリックを使ってメソッドを作成してみよう。
public static <T> T getFirst(T[] array) {
return array[0];
}げげっ、となるところだがポイントを押さえれば難しいことはない。
まず、最初に気になるのが
public static <T>
この部分に登場する<T>ではないだろうか?これは、このメソッドがジェネリクスを使うメソッドであることを宣言している部分だ。もしこれを書かずに
public static T getFirst(T[] array) {}
としてしまうと、T がジェネリクスの型パラメータであることが宣言されていないため、コンパイラは T を既知の型名のように解釈しようとする。しかし、そのような型は定義されていないため、結果としてコンパイルエラーになってしまう。
そのため、ジェネリクスを使うメソッドでは、戻り値の前に <T> などの型パラメータを宣言しなければならない。
ちなみにTというのは慣習的に広く使われているもので文法的はAでもHogeでもなんでもよい。ちなみに慣習的によく使われているものとして代表的はものは以下
T: TypeE: ElementK: KeyV: ValueR: Return
実際のコード
public static <T> T getFirst(T[] array) {
return array[0];
}String[] names={"John","Paul","George","Ringo"};
String firstName = getFirst(names);
System.out.println(firstName);//John
Integer[] nums={100,200,300};
Integer firstNumber=getFirst(nums);
System.out.println(firstNumber);//100なお、このメソッドは T[] を受け取るジェネリクスメソッドであるため、Integer[] のような参照型配列は渡せるが、int[] のような primitive 型の配列は渡せない。この場合は実行時エラーではなく、コンパイルエラーになる。
演習問題
次の仕様を満たす ジェネリクスメソッド printList() を作成しなさい。
Listを引数として受け取ること- リストに含まれる要素を、先頭から順番にすべて表示すること
StringのリストでもIntegerのリストでも使えること
使用例
List<String> names = List.of("John", "Paul", "George", "Ringo");
printList(names);import java.util.List;
public static <T> void printList(List<T> list) {
for (T ele : list) {
System.out.println(ele);
}
}

コメント