Java Gold SE11対策:実務でも試験でも超重要!ワイルドカードとPECS原則の完全理解

Javaの総称型(ジェネリクス)を扱う上で、最もつまずきやすく、試験でも頻出なのが「ワイルドカード」の使い方と「PECS原則」です。
ここではその仕組みと使い分けを徹底解説します!
目次
ワイルドカード ? とは?
総称型を扱うときに登場する ? は、いわば「なんでもOK」のように見える記号。
でも実際には、次のように「制限付き」で使うケースが重要です。
記法 | 読み方 | 意味 |
? extends T | Tのサブ型全般 | Tを継承した型のみ許容 |
? super T | Tのスーパークラス全般 | Tの親型のみ許容 |
例:List<? extends Number>
これは「Numberか、それを継承した型(IntegerやDoubleなど)のListならOK」という意味。
でも、使える操作に制限がある!
次のコードを見てください:
List<? extends Number> list = new ArrayList<Integer>();
Number num = list.get(0); // ✅ OK
list.add(123); // ❌ コンパイルエラー
なぜ add ができないの?
これは、コンパイラが型の安全性を保証できないからです。
たとえば、実際には List<Double> かもしれないのに Integer を追加してしまったら…型エラーですよね。
そこで覚えるべき:PECS原則
PECSとは、Producer Extends, Consumer Super の略。
役割 | 記法 | 使い分けの目安 |
値を受け取る(読み取り専用) | ? extends T | Producer(生産者) |
値を渡す(書き込み専用) | ? super T | Consumer(消費者) |
✅ 例:Producer
List<? extends Number> list = new ArrayList<Integer>();
Number n = list.get(0); // ✅ 読み取りOK
✅ 例:Consumer
List<? super Integer> list = new ArrayList<Number>();
list.add(123); // ✅ 書き込みOK
❌ 両方やりたいときは?
→ ワイルドカードは使えません。型を明示的に指定する必要があります。
List<Integer> list = new ArrayList<>();
list.add(123);
Integer n = list.get(0); // ✅ 読み書き両方OK
Java Gold SE11 試験での狙われポイント
以下のようなコードに対して、コンパイルエラーが起きるかどうかを問う問題が出題されます。
- ? extends T では読み取りはできるが、書き込みはできない
- ? super T では書き込みはできるが、読み取り時の型は Object(または明示的キャストが必要)
- List<Object> に List<String> は代入できない(総称型は共変ではない)
- List<?> は「何も追加できない」汎用読み取り用
これらは覚えておかないと高確率で引っかかります。
まとめ
記法 | 用途 | 操作可能 |
? extends T | 生産者 | 読み取りのみ可 |
? super T | 消費者 | 書き込みのみ可 |
?(無印) | 完全不明 | 読み取りは OK、追加は null のみ |
List<T> | 型確定 | 読み書き両方OK |
そして一番大事なのはこの原則:
読み取りたいなら extends、書き込みたいなら super