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

アイキャッチ画像

Javaの総称型(ジェネリクス)を扱う上で、最もつまずきやすく、試験でも頻出なのが「ワイルドカード」の使い方と「PECS原則」です。
ここではその仕組みと使い分けを徹底解説します!

ワイルドカード ? とは?

総称型を扱うときに登場する ? は、いわば「なんでもOK」のように見える記号。
でも実際には、次のように「制限付き」で使うケースが重要です。

記法読み方意味
? extends TTのサブ型全般Tを継承した型のみ許容
? super TTのスーパークラス全般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 TProducer(生産者)
値を渡す(書き込み専用)? super TConsumer(消費者)

✅ 例: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