泛型通配符extends与super的区别

class Super{
    }
    class Self extends Super{
    }
    class Son extends Self{
    }继承

    void test() {
        List<? extends Self> a = new ArrayList<>();//参数类型上界是Self
        a.add(new Son());//error 不能放入任何类型,由于编译器只知道a中应该放入Self的某个子类,但具体放哪一种子类它并不知道,所以,除了null之外,不能放入任何类型
        a.add(new Self());//error
        a.add(new Super());//error
        a.add(null);//error
        Self s1 = a.get(0); //返回类型是肯定的Self类,由于<? extends T> 只能用于方法返回,告诉编译器此返参的类型的最小继承边界为T,T和T的父类都能接收,可是入参类型没法肯定,只能接受null的传入
        Super s2 = a.get(0); //Self类型能够用Super接收
        Son s3 = a.get(0); //error:子类不能接收父类型参数get

        //--------------------------------------编译器

        List<? super Self> b = new ArrayList<>();//参数类型下界是Self
        b.add(new Son());//ok 只能放入T类型,且知足T类型的超类至少是Self,换句话说,就是只能放入Self的子类型
        b.add(new Self());//ok 自己类型也能够
        b.add(new Super());//ok 超类不能够
        b.add(null);//ok
        Object o1 = b.get(0);//返回类型是未知的, 由于<? super T>只能用于限定方法入参,告诉编译器入参只能是T或其子类型,而返参只能用Object类接收
        Son o2 = b.get(0);//error
        Self o3 = b.get(0);//error
        Super o4 = b.get(0);//error编译

        List<?> c = new ArrayList<>();
        //总结:
        // 1. <? extends T> 只能用于方法返回,告诉编译器此返参的类型的最小继承边界为T,T和T的父类都能接收,可是入参类型没法肯定,只能接受null的传入
        // 2. <? super T>只能用于限定方法入参,告诉编译器入参只能是T或其子类型,而返参只能用Object类接收
        // 3. ? 既不能用于入参也不能用于返参
    }class

相关文章
相关标签/搜索