-
泛型和通配符 ‘?’
虽然 List 和 List 两者之间并不具备继承关系,而是并列关系。但是它们有着一个共同的父类 List<?>。当我们对不同泛型类型的集合进行相同操作的时候,就可以用通配符来进行操纵
例子:
public void iteratorList(List<?> list){ Iterator<?> iter = list.iterator(); while(iter.hasNext()){ Object obj = iter.next(); System.out.println(obj); } }对于使用了通配符的泛型类型集合,只能进行查操作。增删改操作都是不允许的。
-
有限制条件的通配符
-
? extends A(上界通配符)
例子:
class Father{} class Son extends Father{} List<? extends Father> list1 = null; List<Father> list2 = null; List<Son> list3 = null; List<Object> list4 = null; list1 = list2; // true list1 = list3; // true list1 = list4; // falseG<? extends A> 可以看作是 G 和 任何 G<A 的子类> 的父类
-
? super A(下界通配符)
例子:
class Father{} class Son extends Father{} List<? super Father> list1 = null; List<Father> list2 = null; List<Son> list3 = null; List<Object> list4 = null; list1 = list2; // true list1 = list3; // false list1 = list4; // trueG<? super A> 可以看作是 G 和 任何 G<A 的父类> 的父类
-
-
有限制条件通配符的读操作各有不同
-
泛型为 ‘? extendex A’ 的读操作
class Father{} class Son extends Father{} List<? extends Father> s = new List<>(); List<Father> f = null; f = s;上述例子就是说明 泛型为 ‘? extendex A’ 的类 应该被 泛型为此类父类的类 接收
-
泛型为 ‘? super A’ 的读操作
class Father{} class Son extends Father{} List<? super Son> s = new List<>(); List<Father> f = null; f = s;上述例子就是说明 泛型为 ‘? super A’ 的类 至少要被 泛型为此类的父类 接收
-
-
有限制条件通配符的写操作各有不同
写操作是一个上向下兼容的操作。只能写入小,不能写入大的。
限制条件通配符的写操作:限制条件通配符的作用实在 X 轴上找到一个点,点的左边能写入点的右边。
-
泛型为 ‘? extendex A’ 的写操作
class Father{} class Son extends Father{} List<? extends Father> f = new List<>(); f.add(new Son()); // 提示报错这里的上界通配符表示为 Father 类或任何比 Father 小的类,为了不出现写操作混乱,例如写入一级子类但 ‘? extendex A’ 表示的是二级子类。在进行写操作的时候,我们可以把 ‘? extendex A’ 近似看作是一个无限小的一个点,任何类都不能对它进行写操作。
形象解释:上界通配符在 x 轴上出现了一个左开右闭区域。此区域内无论怎么样都找不到最小的左边来写入。所以上界通配符没有写操作。
-
泛型为 ‘? super A’ 的写操作
class Father{} class Son extends Father{} List<? super Father> f = new List<>(); f.add(new Father()); f.add(new Son()); // 全部成功这里的下界通配符表示为 Father 类或任何比 Father 大的类。在进行写操作的时候,我们可以把 ‘? super A’ 这个下界通配符看作在 x 轴上出现一个左闭右开的区域。只要是比此区域小的类都可以进行写操作。即只要是 Father 类或任何 Father 类的子类都可以对此下界通配符修饰的集合进行写操作。
-