Java ジェネリクスの使い方
2025 年 6 月 6 日 by marukorジェネリクスとは
ジェネリクス(Generics)とは、「データ型をパラメータ化して扱う仕組み」です。
クラスやメソッドにおいて、具体的な型を後から指定できるようにすることです。
使い方
ジェネリクスクラス
public class Box<T> { private T value; public void set(T value) { this.value = value; } public T get() { return value; } }
使用例
public class Main { public static void main(String[] args) { Box<String> stringBox = new Box<>(); stringBox.set("こんにちは"); System.out.println(stringBox.get()); Box<Integer> intBox = new Box<>(); intBox.set(100); System.out.println(intBox.get()); } }
Box の T は型のプレースホルダ。使うときに<String> や <Integer> を指定します。
ジェネリクスメソッド
public class Util { public static <T> void printTwice(T item) { System.out.println(item); System.out.println(item); } public static void main(String[] args) { Util.printTwice("Hello"); // String Util.printTwice(123); // Integer } }
メソッドに <T>を定義することで、引数の型に応じて柔軟に対応できます。
応用編
ジェネリクスの**ワイルドカード(<?> , <? extends T> , <? super T>)**
■ ワイルドカードとは?
ワイルドカードは、ジェネリクスの型を柔軟に扱いたいときに使います。
主にコレクション(List, Setなど)を引数に受け取るメソッドで使います。
<?>(無制限ワイルドカード)
意味:どんな型でもOK(型は不明だが何かは入っている)
使用例
public static void printList(List<?> list) { for (Object obj : list) { System.out.println(obj); } } public static void main(String[] args) { List<String> stringList = List.of("A", "B", "C"); List<Integer> intList = List.of(1, 2, 3); printList(stringList); printList(intList); }
※ ただし、要素の追加はできません(型が不明なため)
<? extends T> (上限ワイルドカード)
意味: T またはそのサブクラス(子クラス)である型に限定
使いどころ: 読み取り専用で使いたいとき(読み込みはOK、書き込みはNG)
使用例
public static void printNumbers(List<? extends Number> list) { for (Number num : list) { System.out.println(num.doubleValue()); } }
List<Integer> ints = List.of(1, 2, 3); List<Double> doubles = List.of(1.1, 2.2, 3.3); printNumbers(ints); // OK printNumbers(doubles); // OK
List<? extends Number> なので、Integer や Double も渡せる
ただし、list.add(…) はできません!
<? super T> (下限ワイルドカード)
意味: T またはそのスーパークラス(親クラス)である型に限定
使いどころ: 書き込み(追加)だけしたいときに使う(読み取りは Object 型として扱う)
使用例
public static void addNumbers(List<? super Integer> list) { list.add(1); list.add(2); }
List<Object> objs = new ArrayList<>(); addNumbers(objs); // OK List<Number> nums = new ArrayList<>(); addNumbers(nums); // OK
List<? super Integer> なので、Integer の親クラスである Number や Object も許可 追加は Integer 型としてできるが、取り出すときは Object 型としてしか扱えない
まとめ
extends → 「上から読めるけど、下に書き込めない(読み取り専用)」
super → 「下に書き込めるけど、型がわからないから読み取りは制限(追加専用)」
タグ: Java