ジェネリクスの概念

Javaの「ジェネリクス(Generics)」とは、クラスやメソッドが扱うデータ型を、コードを記述する段階ではなく、実行時ではなく「コンパイル時」に指定できるようにする仕組みです。これにより、型安全性を高めつつ、コードの再利用性を向上させることができます。


1. ジェネリクスの基本的な目的

  • 型安全性の確保
    実行時に型キャストエラーが発生するのを防ぎ、コンパイル時にエラーを検出できます。

  • キャストの不要化
    型を明示することで、不要なキャストを省略できます。

  • コードの再利用
    複数の型に対応した汎用的なクラスやメソッドを記述できます。


2. 基本的な使い方(例:ジェネリッククラス)

java
public class Box<T> { private T value; public void set(T value) { this.value = value; } public T get() { return value; } }

このクラスは、任意の型Tの値を保持できます。Tは「型パラメータ」と呼ばれ、実際の使用時に具体的な型に置き換えます。

java
Box<String> stringBox = new Box<>(); stringBox.set("Hello"); String value = stringBox.get(); // キャスト不要

3. ジェネリックメソッドの例

java
public class Util { public static <T> void printArray(T[] array) { for (T element : array) { System.out.println(element); } } }

呼び出し例:

java
Integer[] numbers = {1, 2, 3}; Util.printArray(numbers);

4. ワイルドカード(?

  • ? は不特定の型を表すワイルドカードで、柔軟なメソッド設計に役立ちます。

java
public void printList(List<?> list) { for (Object elem : list) { System.out.println(elem); } }

5. バウンディング(境界指定)

特定の型やそのサブクラスに制限することも可能です。

  • <? extends Number>Numberまたはそのサブクラス

  • <? super Integer>Integerまたはそのスーパークラス

java
public void process(List<? extends Number> list) { // listに格納されるのはNumberのサブクラス }

6. ジェネリクスの制限

  • ジェネリック型の配列は作成できない(例:new T[] は不可)

  • staticメンバーでジェネリック型パラメータは使えない

  • instanceofのチェックに型パラメータは使えない(例:if (obj instanceof T) は不可)


まとめ

Javaのジェネリクスは、型の安全性、キャストの不要化、コードの再利用性を目的として導入されました。クラス、インターフェース、メソッドなどで活用され、特にコレクションフレームワーク(List, Map, Setなど)では広く使われています。

生成日:2025/05/03