1.通配符的使用
通配符:?
类A是类B的父类,G<A>和G<B>是没关系的,二者共同的父类是:G<?>
//注意点1: 编译错误:不能用在泛型方法声明上,返回值类型前面<>不能使用?
public static <?> void test(ArrayList<?> list){
}
//注意点2: 编译错误:不能用在泛型类的声明上
class GenericTypeClass<?>{
}
//注意点3: 编译错误:不能用在创建对象上,右边属于创建集合对象
ArrayList<?> list2 = new ArrayList<?>()
2.涉及通配符的集合的数据的写入和读取:
读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型 是什么,它包含的都是Object。
写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中 添加对象。 唯一的例外是null,它是所有类型的成员
List<Object> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<?> list = null;
list = list1;
list = list2;
print(list1);
print(list2);
List<String> list3 = new ArrayList<>();
list = list3;
//添加(写入):对于List<?>就不能向其内部添加数据。
//除了添加null之外。
// list.add("AA");编译不通过
// list.add("?");编译不通过
list.add(null);
//获取(读取):允许读取数据,读取的数据类型为Object。
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);
}
}
3.有限制条件的通配符的使用
? extends A:
G<? extends A> 可以作为G<A>和G<B>的父类,其中B是A的子类
? super A:
G<? super A> 可以作为G<A>和G<B>的父类,其中B是A的父类
public void test4(){
List<? extends Person> list1 = null;
List<? super Person> list2 = null;
ArrayList<Object> objects = new ArrayList<Object>();
ArrayList<Person> person = new ArrayList<Person>();
ArrayList<Student> student = new ArrayList<Student>();
//list1 = objects;编译不通过
list1 = person;
list1 = student;
list2 = objects;
list2 = person;
// list2 = Student;//编译不通过
//读取数据:
list1 = student;
Person p1 = list1.get(0);
//编译不通过
// Student s1 = list1.get(0);
list2 = person;
Object o1 = list2.get(0);
//编译不通过
// Person p2 = list2.get(0);
//写入数据
//编译不通过
// list1.add(new Student());
//编译通过(子类的引用可以赋给父类的对象)
list2.add(new Person());
list2.add(new Student());
}