类型通配符:?

比如:List<?> ,Map<?,?>
List<?>是List、List等各种泛型List的父类。

使用说明

  • 读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object。
  • 写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中添加对象。

唯一的例外是null,它是所有类型的成员。

  1. public static void main(String[] args) {
  2. List<?> list = null;
  3. list = new ArrayList<String>();
  4. list = new ArrayList<Double>();
  5. // list.add(3);//编译不通过
  6. list.add(null);
  7. List<String> l1 = new ArrayList<String>();
  8. List<Integer> l2 = new ArrayList<Integer>();
  9. l1.add("hello");
  10. l2.add(15); 7+
  11. read(l1);
  12. read(l2);
  13. }
  14. public static void read(List<?> list) {
  15. for (Object o : list) {
  16. System.out.println(o);
  17. }
  18. }
  1. //注意点1:编译错误:不能用在泛型方法声明上,返回值类型前面<>不能使用?
  2. public static <?> void test(ArrayList<?> list){
  3. }
  4. //注意点2:编译错误:不能用在泛型类的声明上
  5. class GenericTypeClass<?>{
  6. }
  7. //注意点3:编译错误:不能用在创建对象上,右边属于创建集合对象
  8. ArrayList<?> list2 = new ArrayList<?>();

有限制的通配符

  • <?>

允许所有泛型的引用调用

  • 通配符指定上限

上限extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<=
< ? extends Number>只允许泛型为Number及Number子类的引用调用

  • 通配符指定下限

下限super:使用时指定的类型不能小于操作的类,即>=
< ? super Number> 只允许泛型为Number及Number父类的引用调用

  1. public void test4(){
  2. List<? extends Person> list1 = null;
  3. List<? super Person> list2 = null;
  4. List<Student> list3 = new ArrayList<Student>();
  5. List<Person> list4 = new ArrayList<Person>();
  6. List<Object> list5 = new ArrayList<Object>();
  7. list1 = list3;
  8. list1 = list4;
  9. // list1 = list5;
  10. // list2 = list3;
  11. list2 = list4;
  12. list2 = list5;
  13. //读取数据:
  14. list1 = list3;
  15. Person p = list1.get(0);
  16. //编译不通过
  17. //Student s = list1.get(0);
  18. list2 = list4;
  19. Object obj = list2.get(0);
  20. ////编译不通过
  21. // Person obj = list2.get(0);
  22. //写入数据:
  23. //编译不通过
  24. // list1.add(new Student());
  25. //编译通过
  26. list2.add(new Person());
  27. list2.add(new Student());
  28. }