List<? extends Fruit> list 并不是说能添加 Fruit 子类的任意类型到 list 中。而是说<?extends Fruit>通配符实际上代表一种特定的类型,它只是表示 “某种特定的类型,但是 flist 没有指定“。就比如 flist2 里面声明的是 Banana 泛型,flist 声明的是 Apple 泛型 。 所以说 List<? extends Fruit> list 不能添加。因为其实从 List<? extends Fruit> 来看,这个集合会存什么样的 Fruit 子类它自己是未知的
但是 Apple a = (Apple)flist.get(0) 是可以的。在这个 List 中,不管它实际的类型到底是什么,但肯定能转型为 Fruit ,都是继承了 Fruit 的类,所以编译器允许返回 Fruit 。
其次是 ? super T 的疑惑
a5 继承了 a4 ,a4 继承了 a3 ,a3 继承了 a2. a2 继承了 a1 ? super T 可以按照下面这么写 List<? super a5> a5List = new ArrayList<a5>(); List<? super a5> a4List = new ArrayList<a4>(); List<? super a5> a3List = new ArrayList<a3>(); List<? super a5> a2List = new ArrayList<a2>(); List<? super a5> a1List = new ArrayList<a1>();
我们可以知道向这些 List 添加一个 a5 或者其子类型的对象是安全的,这些对象都可以向上转型为 Apple 。