public static void main(String[] args) { A a = new A(); B b = new B(); C c = new C(); D d = new D(); List<A> as = new ArrayList<>(); as.add(a); as.add(b); as.add(c); List<B> bs = new ArrayList<>(); bs.add(b); bs.add(c); // error // bs.add(a); List<C> cs = new ArrayList<>(); cs.add(c); // error // cs.add(a); // cs.add(b); List<D> ds = new ArrayList<>(); ds.add(d); List<? extends A> test1 = as; List<? extends A> test2 = bs; List<? extends A> test3= cs; List<? extends A> testd= ds; // 可以放任意子类的实现,对象可以直接调用他的任意方法 test1.get(0).testA(); // 这里的实际类型可能是 as bc cs ds, 所以其实往里面添加其实都是不安全的(我按照赋值进行了向下转换转换都存在无法设置的情况) // ((List<D>)testd).add(a); // ((List<B>)test2).add(d); // ((List<C>)test3).add(b); // ((List<D>)testd).add(c); List<? super B> test4 = as; List<? super B> test5 = bs; // error // List<? super B> test6 = cs; // 因为可以赋值的是任意其父类,所以只有调用Object的方法都是安全的 test4.get(0).hashCode(); // 设的是他的子类是,他必然也是? super B的子类,所以也是绝对安全的 ((List<B>)test5).add(c); } static class A{ void testA(){} } static class B extends A{ void testB(){} } static class D extends A{ void testD(){} } static class C extends B{ void testC(){} }