- static class Food{}
- static class Fruit extends Food{}
- static class Apple extends Fruit{}
- static class RedApple extends Apple{}
- List<? extends Fruit> flist = new ArrayList<Apple>();
- // complie error:
- // flist.add(new Apple());
- // flist.add(new Fruit());
- // flist.add(new Object());
- flist.add(null); // only work for null
List<? extends Frut> 表示 "具有任何从 Fruit 继承类型的列表",编译器无法确定 List 所持有的类型,所以无法安全的向其中添加对象。可以添加 null, 因为 null 可以表示任何类型。所以 List 的 add 方法不能添加任何有意义的元素,但是可以接受现有的子类型 List<Apple> 赋值。
- Fruit fruit = flist.get(0);
- Apple apple = (Apple)flist.get(0);
由于,其中放置是从 Fruit 中继承的类型,所以可以安全地取出 Fruit 类型。
- flist.contains(new Fruit());
- flist.contains(new Apple());
在使用 Collection 中的 contains 方法时,接受 Object 参数类型,可以不涉及任何通配符,编译器也允许这么调用。
- List<? super Fruit> flist = new ArrayList<Fruit>();
- flist.add(new Fruit());
- flist.add(new Apple());
- flist.add(new RedApple());
- // compile error:
- List<? super Fruit> flist = new ArrayList<Apple>();
List<? super Fruit> 表示 "具有任何 Fruit 超类型的列表",列表的类型至少是一个 Fruit 类型,因此可以安全的向其中添加 Fruit 及其子类型。由于 List<? super Fruit> 中的类型可能是任何 Fruit 的超类型,无法赋值为 Fruit 的子类型 Apple 的 List<Apple>.
- // compile error:
- Fruit item = flist.get(0);
因为,List<? super Fruit> 中的类型可能是任何 Fruit 的超类型,所以编译器无法确定 get 返回的对象类型是 Fruit, 还是 Fruit 的父类 Food 或 Object.
- extends 可用于的返回类型限定,不能用于参数类型限定。
- super 可用于参数类型限定,不能用于返回类型限定。
- >带有super超类型限定的通配符可以向泛型对易用写入,带有extends子类型限定的通配符可以向泛型对象读取。
来源: