java協變逆變,PECS

吳X發表於2017-10-11
    public static void main(String[] args) {
        // Object <- Fruit <- Apple <- RedApple
        System.out.println(Apple.class.isAssignableFrom(Fruit.class));
        System.out.println(Fruit.class.isAssignableFrom(Fruit.class));
        System.out.println(Fruit.class.isAssignableFrom(Apple.class));  // apple 是 Fruit子類

        // 協變
        List<Apple> apples = new ArrayList<Apple>();
        List<? extends Fruit> listfruits = apples;
//        listfruits.add(new Apple());
//        listfruits.add(new RedApple());
//        listfruits.add(new Fruit());  // ERROR: 不能夠往一個使用了? extends的資料結構裡寫入任何的值。
        Fruit f = listfruits.get(0);

        // 逆變
        List<Fruit> fruits = new ArrayList<Fruit>();
        List<? super Apple> list2 = fruits;
//        list2.add(new Fruit());   //ERROR
        list2.add(new Apple());
        list2.add(new RedApple());
//        Fruit f = list2.get(0);   //ERROR

        /*
        存取原則和PECS法則
        總結 ? extends 和 the ? super 萬用字元的特徵,我們可以得出以下結論:

        如果你想從一個資料型別裡獲取資料,使用 ? extends 萬用字元
        如果你想把物件寫入一個資料結構裡,使用 ? super 萬用字元
        如果你既想存,又想取,那就別用萬用字元。
        這就是Maurice Naftalin在他的《Java Generics and Collections》這本書中所說的存取原則,
        以及Joshua Bloch在他的《Effective Java》這本書中所說的PECS法則。
        Bloch提醒說,這PECS是指”Producer Extends, Consumer Super”,這個更容易記憶和運用。
        * */
    }

  http://www.cnblogs.com/softidea/p/4106659.html

相關文章