ジェネリクスとは
ジェネリクスはプログラムの型安全性を向上させるための機能で、
JavaSE5から導入されました。
クラスやメソッドのパラメーター(引数)や戻り値に型を指定できるため、型に関するエラーがコンパイル時点で検知できるようになり安全なプログラムを組むことができます。
ジェネリクスを使うことで以下のようなメリットがあります。
- 型安全性の向上
- ジェネリクスを使用することでコンパイル時に型のチェックが可能となり、実行時ではなくコンパイル時に検知されます。そのためプログラムの安全性が向上します。
- 型キャストの省略
- ジェネリクスを使用することで型が明確になるため、コーディング時にキャスト(型変換)が不要となります。そのためプログラムの可読性が向上します。
- 再利用性の向上
- ジェネリクスを使用することで、同じクラスやメソッドを異なる型で使用できるため、コードの再利用性が高まります。
ジェネリクス構文
ジェネリクスはクラス、メソッド、コレクション宣言で使用できます。
- (クラスにジェネリクスを指定する構文)
- [修飾子] class クラス名 <型パラメータ> { }
- (メソッドにジェネリクスを指定する構文)
- [修飾子] <型パラメータ> 戻り値型 メソッド名(型 引数) { }
- (コレクション生成時にジェネリクスを指定する構文)
- コレクション型<型パラメータ> 変数名 = new コレクション型<型パラメータ>
型パラメータ | 意味 |
---|---|
<T> | 型パラメータ(T)に指定した型に対応する |
<?> | 未知の型に対応する 読み取り専用の操作しかできない ※非境界ワイルドカード |
<? extends T> | 型パラメータ(T)に指定した型とそのサブクラスに対応する ※境界ワイルドカード |
<? super T> | 型パラメータ(T)に指定した型とそのスーパークラスに対応する ※境界ワイルドカード |
※型パラメータに使用される英字は慣例的に以下のものが使用されます。
T(Type)、E(Element)、K(Key)、V(Value)
ジェネリクスサンプル
クラスにジェネリクスを指定したサンプルです。
- (クラスにジェネリクスを指定した例)
-
public class Box<T> { private T content; public Box(T content) { this.content = content; } public T getContent() { return content; } public void setContent(T content) { this.content = content; } }
上記のBoxクラスは以下のような感じで使用できます。
- (ジェネリクスを使用したクラスをnewする例)
-
//Integer型を指定してnewした例 Box<Integer> iBox = new Box<Integer>(); iBox.setContent(123); System.out.println(iBox.getContent()); //String型を指定してnewした例 Box<String> sBox = new Box<String>(); sBox.setContent("Hello!"); System.out.println(iBox.getContent());
ダイヤモンド演算子
ダイヤモンド演算子はインスタンス化する時、型推論ができる場合はジェネリック型を省略する機能です。JavaSE7で導入されました。
- (ダイヤモンド演算子を使用した例と使用しない例)
-
//ダイヤモンド演算子を使用しない例 List<String> list = new ArrayList<String>(); Map<Integer, String> map = new HashMap<><Integer, String>(); //ダイヤモンド演算子を使用した例 List<String> list = new ArrayList<>(); Map<Integer, String> map = new HashMap<>();
変数を指定しない場合はObjectが指定されたとみなされます。
(例)ArrayList list = new ArrayList<>();
ジェネリクスまとめ
- JavaSE5から導入されたプログラムの型安全性を向上させるための機能
- クラス定義時に使用すると、クラスの再利用性が高まる
- 使用する型が明確になるため、不正な型はコンパイル時に発見できるようになる
- 型推論ができる場合はダイヤモンド演算子が使用できる(JavaSE7以降)
コメント