通配符的使用
通配符:?
类A是类B的父类,G<A>和G<B>是没有关系的,二者共同的父类是:G<?>
@Test
public void test3(){
List<Object> list1 = null;
List<String> list2 = null;
List<?> list = null;
list = list1;
list = list2;
List<String> list3 = new ArrayList<>();
list3.add("AA");
list3.add("BB");
list3.add("CC");
list = list3;
list.add(null);
Object o = list.get(0);
System.out.println(o);
}
public void print(List<?> list){
Iterator<?> iterator = list.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
}
=====================================================================
有限制条件的通配符的使用
? extends A:
G<? extends A> 可以作为G<A>和G<B>的父类,其中B是A的子类
? super A:
G<? super A> 可以作为G<A>和G<B>的父类,其中B是A的父类
看下面的代码(64-87行)理解这两句话:
@Test
public void test4(){
List<? extends Person> list1 = null;
List<? super Person> list2 = null;
List<Student> list3 = new ArrayList<Student>();
List<Person> list4 = new ArrayList<Person>();
List<Object> list5 = new ArrayList<Object>();
list1 = list3;
list1 = list4;
**相反的,super可以看成 >=;在下面代码中,>=Person的类都可以赋值给list2.**
-----
list2 = list4;
list2 = list5;
- //通过对上面代码的理解:应用场景 <? extends Comparable> // 只允许泛型为实现Comparable接口的实现类的引用调用
---------------------
list1 = list3;
Person p = list1.get(0);
list2 = list4;
Object obj = list2.get(0);
===========================================================
当你将一个变量声明为List<? extends Person>时,它表示一个未知类型的列表,该类型是Person的子类型或扩展类型。
它可以是Student、Teacher或Person的任何其他子类。
然而,编译器无法在运行时确定list1可以持有的具体Person子类型。
它可能是Student或任何其他子类,因此向这样的列表中添加元素是不安全的。
编译器会阻止你向列表中添加元素,因为无法保证被添加的元素与未知子类型兼容。
如果你想向列表中添加元素,应该将其声明为List<Person>,而不是List<? extends Person>。这样,
列表可以保存任何Person类型或其子类的对象,包括Student,你就可以将Student对象添加到列表中而不会出现编译错误。
list2.add(new Person());
list2.add(new Student());
}
}
===========
## 注意点
============
~~~java
public static <?> voidtest(ArrayList<?> list){
}
class GenericTypeClass<?>{
}
ArrayList<?> list2 = new ArrayList<?>();
List<?> list = null;
通配符可以用在一般方法的参数上和对象的声明上。
~~~
##