Java のジェネリックスで境界ワイルドカード型のパラメータを使用するときに、<? extends T> と <? super T> どちらを指定すればいいか迷っていた時期がありました。
今日はなぜか TL でジェネリックスの話題が多く *1 、当時のことを思い出したので懐古エントリを書いてみます。
PECS イディオム
Java で境界ワイルドカード型のパラメータを使用するときのイディオムは良く知られていて、Effective Java では以下のように述べられています。
どちらのワイルドカード型を使用すべきかを覚えるための略語は、次の通りです。
PECS は、プロデューサー (producer) -extends、コンシューマー (consumer) -super を表わしています。
プロデューサーの場合には <? extends T>、コンシューマーの場合には <? super T> を指定する、簡単です…なのですが、実際に使う段になると慣れないうちは「あれ? これは PECS の P と C どっちになるのかな?」といったことがありました。
Collections.copy
そんな時にふと見た Collections.copy のメソッドシグニチャー。
これがすごく分かりやすい。
パラメータ dest がコンシューマー (消費者)、src が プロデューサー (生産者) というのが一目瞭然です。
そう思わなくても境界ワイルドカード型の適用の仕方がまんま書いてあります。
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
こういうのに頼るのはあまり良くないかもしれませんが、おかげで今では PECS を自然に扱えるようになりました。
ジェネリックス、まだまだ使いこなせていませんが便利ですねぇ。 *2
Effective Java 第2版 (The Java Series)
- 作者: Joshua Bloch,柴田芳樹
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2008/11/27
- メディア: 単行本(ソフトカバー)
- 購入: 77人 クリック: 936回
- この商品を含むブログ (267件) を見る