Java のジェネリックスについて

Java のジェネリックスについて

このページでは、Java のジェネリックスについて詳しく解説します。基本的な概念から、使い方、応用例、制限事項まで幅広く説明します。

ジェネリックスとは

Java のジェネリックスは、型をパラメータとして扱う仕組みを提供します。これにより、型安全性を確保し、コードの再利用性を向上させることができます。

たとえば、リストに異なる型のデータを追加するときに、ジェネリックスを使えば不適切な型のデータを防ぐことができます。

ジェネリックスの利点

  • 型安全性の向上: コンパイル時に型チェックを行うことで、実行時のエラーを防ぎます。
  • キャストの不要化: 明示的な型キャストが不要になります。
  • コードの再利用性: 同じコードを異なる型で簡単に再利用できます。

基本的な構文

ジェネリックスは、クラス、インターフェース、およびメソッドに適用できます。

ジェネリッククラス


class Box {
    private T item;

    public void setItem(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }
}

public class Main {
    public static void main(String[] args) {
        Box stringBox = new Box<>();
        stringBox.setItem("Hello");
        System.out.println(stringBox.getItem());

        Box intBox = new Box<>();
        intBox.setItem(123);
        System.out.println(intBox.getItem());
    }
}
    

ジェネリックメソッド


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

    public static void main(String[] args) {
        String[] stringArray = {"A", "B", "C"};
        Integer[] intArray = {1, 2, 3};

        printArray(stringArray);
        printArray(intArray);
    }
}
    

ワイルドカード

ジェネリックスには「ワイルドカード」という特殊な表現があり、柔軟な型指定が可能です。

ワイルドカードの基本


public void printList(List list) {
    for (Object obj : list) {
        System.out.println(obj);
    }
}
    

境界付きワイルドカード


public void addNumbers(List list) {
    list.add(10);
    list.add(20);
}

public void printNumbers(List list) {
    for (Number num : list) {
        System.out.println(num);
    }
}
    

ジェネリックスの制限

  • プリミティブ型は使用できない: ジェネリックスはオブジェクト型にのみ適用可能です(ラッパークラスを使用します)。
  • 型情報の消去: 実行時には型情報が消去されます(タイプイレージョン)。
  • 静的メンバーにジェネリックスは使用不可: 静的メソッドやフィールドに型パラメータを持たせることはできません。

応用例

ジェネリックスタックの実装


class Stack {
    private List elements = new ArrayList<>();

    public void push(T element) {
        elements.add(element);
    }

    public T pop() {
        if (elements.isEmpty()) {
            throw new EmptyStackException();
        }
        return elements.remove(elements.size() - 1);
    }

    public boolean isEmpty() {
        return elements.isEmpty();
    }
}

public class Main {
    public static void main(String[] args) {
        Stack stack = new Stack<>();
        stack.push(10);
        stack.push(20);
        System.out.println(stack.pop());
        System.out.println(stack.pop());
    }
}
    

複数の型パラメータ


class Pair {
    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public V getValue() {
        return value;
    }
}

public class Main {
    public static void main(String[] args) {
        Pair pair = new Pair<>("Age", 30);
        System.out.println("Key: " + pair.getKey());
        System.out.println("Value: " + pair.getValue());
    }
}
    

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です