Javaジェネリクス完全ガイド:再利用可能で型安全なコードの構築
Javaジェネリクス – 再利用可能で型安全なコードの構築
Javaジェネリクス、ジェネリッククラスとメソッドの作り方、それらがもたらすメリットを明確な例で解説します。
Javaジェネリクスを使用すると、コンパイル時安全性を保ちながら、多くの異なるデータ型で動作する1つのクラス、インターフェース、メソッドを記述できます。
注意: ジェネリクスはプリミティブ型(int、float、charなど)では動作しません。
Javaジェネリクスクラス
型パラメータを宣言することで、任意のオブジェクト型で動作するクラスを作成できます。
例:ジェネリッククラスの作成
class Main {
public static void main(String[] args) {
GenericsClass<Integer> intObj = new GenericsClass<>(5);
System.out.println("ジェネリッククラスの返却値: " + intObj.getData());
GenericsClass<String> stringObj = new GenericsClass<>("Java Programming");
System.out.println("ジェネリッククラスの返却値: " + stringObj.getData());
}
}
class GenericsClass<T> {
private T data;
public GenericsClass(T data) {
this.data = data;
}
public T getData() {
return this.data;
}
}
出力
ジェネリッククラスの返却値: 5 ジェネリッククラスの返却値: Java Programming
上記例では、GenericsClassはTを型パラメータとするジェネリッククラス。2つのインスタンスを作成:
- intObj – Tが
Integerに置き換えられ、整数で動作 - stringObj – Tが
Stringに置き換えられ、文字列で動作
Javaジェネリクスメソッド
メソッドもジェネリック化でき、型安全性を保ちながら任意の型の引数を受け取れます。
例:ジェネリックメソッドの作成
class Main {
public static void main(String[] args) {
DemoClass demo = new DemoClass();
demo.<String>genericsMethod("Java Programming");
demo.<Integer>genericsMethod(25);
}
}
class DemoClass {
public <T> void genericsMethod(T data) {
System.out.println("ジェネリックメソッド:");
System.out.println("渡されたデータ: " + data);
}
}
出力
ジェネリックメソッド: 渡されたデータ: Java Programming ジェネリックメソッド: 渡されたデータ: 25
コンパイラが型を推論できる場合、明示的な型引数を省略可能:
demo.genericsMethod("Java Programming");
境界付き型(Bounded Types)
ジェネリック型に特定のクラスファミリのみ受け入れさせたい場合があります。境界付き型はextendsキーワードで実現します。
構文: <T extends A> – TはAまたはAのサブタイプ。
例:境界付き型
class GenericsClass <T extends Number> {
public void display() {
System.out.println("これは境界付き型ジェネリッククラスです。");
}
}
class Main {
public static void main(String[] args) {
// GenericsClass<String> obj = new GenericsClass<>(); // コンパイルエラー
}
}
ここではGenericsClassは数値型(Integer、Doubleなど)のみ受け入れます。Stringでインスタンス化しようとするとコンパイル時エラー:
GenericsClass<String> obj = new GenericsClass<>(); ^ reason: inference variable T has incompatible bounds equality constraints: String lower bounds: Number where T is a type-variable: T extends Number declared in class GenericsClass
Javaジェネリクスの利点
1. コード再利用性
ジェネリックコードは複数のデータ型で動作し、重複を削減。例えば1つのメソッドで整数、文字列、カスタムオブジェクトを処理可能。
2. コンパイル時型チェック
型パラメータがコンパイル時に判明するため、コンパイラが実行前に型不一致を検出可能。
3. コレクションとのシームレスな統合
Javaのコレクションフレームワークはジェネリクスベースで、コレクションが型安全性を強制可能。例:
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
他のコレクションクラス(LinkedList、Queue、Mapなど)も同じメリットでジェネリクスを使用。
Java
- Javaのfinalキーワード完全解説:変数、メソッド、クラスでの活用法
- Java instanceof演算子完全ガイド:基本から継承・インターフェースまで
- Java継承のマスター:概念、種類、実践例
- Java Staticネストクラスの理解:用法、違い、実例
- Java無名インナークラス完全ガイド:定義、構文、実践例
- Javaシングルトンパターン完全解説:安全な実装と活用法
- Javaリフレクション完全ガイド:実行時のクラス・メソッド・フィールド検査
- Java ArrayList完全マスター:操作・メソッド・ベストプラクティス
- Java Stackクラス完全ガイド:使い方と主要メソッド
- Java ObjectOutputStream完全ガイド:シリアル化、メソッド、実践例
- Javaファイル操作のマスター:java.ioによる作成・読み取り・書き込み・削除