特に
<? super Hoge>
というのがわからん。
…と思ってたのだけど、少しわかってきた。ような。
- <? super Hoge>型にはHogeかそのスーパークラスが代入できる
<? extends Hoge>型にはHogeかサブクラスしか代入できない - 受けた側では、Hogeかそのサブクラスを代入できる
- <? extends Hoge>で受けるとnullしか代入できない
<Hoge>で受けると同じくHogeとサブクラスを代入できる - 渡した側は、少なくともHoge型として扱えるものが代入されるとわかる
要は、を使うのはたぶん、引数のリストに何か詰めて返すような処理でかつ、型を現在わかる最上位で固定したくない場合、のような、普通はあまり必然性が高くなさそうな状況ということでオーケーなんだろか。下限が決まらんということはあっても上限が決まらんということはそう多くない気がするが。…絶対ないとも言えないのはわかるけど。スーパープログラマには必要なアレなのかね?
↓確認コード。素人ぽい?まあ、そりゃ親切のためだよ、きっと。
import java.util.ArrayList; import java.util.List; public class Generics { public static void main(String[] arg){ List<Monkey> monkeys = new ArrayList<Monkey>(); //addTo(monkeys);//compile error. 行けそうなものだが行けない //addTo_super(monkeys);//compile error. superじゃないし addTo_extends(monkeys);//メソッド内でmonkeysにnullしかadd出来ないが List<Animal> animals = new ArrayList<Animal>(); addTo(animals); addTo_super(animals); addTo_extends(animals); //List<Creature> creatures = l;//通常の変数のようにサブクラスに代入できない List<Creature> creatures = new ArrayList<Creature>(); //addTo(creatures);//compile error addTo_super(creatures);//Animalかサブクラスが足される。Objectなどは来ない。 //addTo_extends(creatures);//compile error } static void say(List<? extends Animal> l){ for(Object a : l) ((Animal)a).say(); } static void addTo(List<Animal> l){ l.add(new Animal()); l.add(new Monkey()); l.add(new Human()); //l.add(new Creature());//compile error } // メソッド内では型はAnimal以下限定。外では上限定。 static void addTo_super(List<? super Animal> l){ l.add(new Animal()); l.add(new Monkey()); l.add(new Human()); //l.add(new Creature());//compile error } // 何も足せない static void addTo_extends(List<? extends Animal> l){ //l.add(new Animal());//compile error //l.add(new Monkey());//compile error //l.add(new Human());//compile error //l.add(new Creature());//compile error } } class Creature{ void say(){ System.out.println("Yes, I am a(n) " + this.getClass().getSimpleName()); } } class Animal extends Creature{ } class Monkey extends Animal{ } class Human extends Monkey{ }