はじめに
最近お仕事の都合で、Java を使う機会に恵まれたので
太古のJava( 1.3 )知識をアップデートしてみました。
Generics とは
利用する型の処理を実装時に確定する機能です。
これだけでは何のことかさっぱりなので、例を出しつつ説明したいと思います。
Generics 有無をコードで比較
Java1.3の頃のコード
List list = new ArrayList();
// list に値を格納
// String -> Object への変換なので暗黙的に格納出来る
list.add("1");
list.add("2");
list.add("3");
for (Iterator it = list.iterator(); it.hasNext(); ) {
// list の値を取得して表示
// 取得時は Object -> String は明示的なキャストが必要
String str = (String) it.next();
System.out.println(str);
}
Java8のコード
// String 型を利用するArrayList を準備
List<String> list = new ArrayList<String>();
// List<String> list = new ArrayList<>(); // 変数宣言時に型が確定しているので、インスタンス作成時は <> と省略可能
// list に値を格納
// String をそのまま格納出来る
list.add("1");
list.add("2");
list.add("3");
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
// list の値を取得して表示
// String で取得できるのでキャスト不要
String str = it.next();
System.out.println(str);
}
使うと何が良いの?
Java1.3 では、コレクションを使う場合
Object 型で格納する必要がありました。
当然、取り出すときもObject 型なので、使う型に合わせてキャストする必要がありました。
この取り出し時にキャストするというのが曲者で
格納する型を間違えると、ClassCastException が発生してしまいます。
当然ながらException なので実行してみないと間違いに気が付かないのです。
一方で Generics を使うと、実装時に型の確定が出来るので
格納する型を間違える=コンパイルエラーが発生
と、イージーミスの削減にも役立つ機能です。