首页 > 编程语言 > 详细

操作 Java 泛型(三):泛型在继承方面体现与通配符使用

时间:2021-05-23 23:18:33      阅读:19      评论:0      收藏:0      [点我收藏+]

一、泛型在继承上的体现

  1、先看两段代码有何不同

    片段1:

1   public void printCollection(Collection c) {
2         Iterator i = c.iterator();
3         for (int k = 0; k < c.size(); k++) {
4             System.out.println(i.next());
5         }
6     }

 

      片段2:

1   public void printCollection(Collection<Object> c) {
2         for (Object e : c) {
3             System.out.println(e);
4         }
5     }

 

  2、泛型在继承上的体现

    如果BA的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口, G<B>并不是G<A>的子类型!

    比如: StringObject的子类,但是List<String >并不是List<Object>的子类。

    技术分享图片

     但是:如果类 A 是类 B的父类,A<G> 是 B<G> 的父类。

 

  3、代码体验

    实验一:

 1     @Test
 2     public void test(){
 3 
 4         Object obj = null;
 5         String str = null;
 6         obj = str;
 7 
 8         Object[] arr1 = null;
 9         String[] arr2 = null;
10         arr1 = arr2;
11 
12 
13         //编译不通过
14         //Date date = new Date();
15         //str = date;
16 
17 
18         List<Object> list1 = null;
19         List<String> list2 = new ArrayList<String>();
20         //此时的list1和list2的类型不具有子父类关系
21         //编译不通过
22         //list1 = list2;
23         
24     }

 

    实验二:

 1   public void testGenericAndSubClass() {
 2         Person[] persons = null;
 3         Man[] mans = null;
 4         // 而 Person[] 是 Man[] 的父类.
 5         persons = mans;
 6         
 7         Person p = mans[0];
 8         
 9         
10         // 在泛型的集合上
11         List<Person> personList = null;
12         List<Man> manList = null;
13         // personList = manList;(报错)
14     }

 

    实验三:

 1     public void test(){
 2 
 3         AbstractList<String> list1 = null;
 4         List<String> list2 = null;
 5         ArrayList<String> list3 = null;
 6 
 7         list1 = list3;
 8         list2 = list3;
 9 
10         List<String> list4 = new ArrayList<>();
11 
12     }

 

 

二、通配符的使用

  1、通配符

    (1)使用类型 通配符:?
      比如: List<?> Map<?,?>
      List<?>List<String>List<Object>等各种泛型List的父类。
    (2)读取 List<?> 的对象 list 中的元素时,永远是安全的,因为不管 list 的真实类型是什么,它包含的都是Object
    (3)写入 List中的元素时,不行。因为我们不知道 的元素类型,我们不能向其中添加对象。
        注意:唯一的例外是可以写入null,它是所有类型的成员。

  2、案例一

 1     @Test
 2     public void test() {
 3         List<Object> list1 = null;
 4         List<String> list2 = null;
 5 
 6         List<?> list = null;
 7 
 8         list = list1;
 9         list = list2;
10 
11         //编译通过
12         //print(list1);
13         //print(list2);
14 
15         
16     }
17 
18     public void print(List<?> list){
19         Iterator<?> iterator = list.iterator();
20         while(iterator.hasNext()){
21             Object obj = iterator.next();
22             System.out.println(obj);
23         }
24     }

 

    List<?> 作为 List<String> 和List<Object> 的父类。

 

  3、通配符的使用——读取操作

    (1)将任意元素加入到其中不是类型安全的:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // 编译时错误

      因为我们不知道c的元素类型,我们不能向其中添加对象。 add方法有类型参数E作为集合的元素类型。

      我们传给add的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。

    (2)唯一的例外的是null,它是所有类型的成员。
    (3)另一方面,我们可以调用get()方法并使用其返回值。返回值是一个未知的类型,但是我们知道,它总是一个Object

  4、案例

 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         
 8         
 9         List<String> l1 = new ArrayList<String>();
10         List<Integer> l2 = new ArrayList<Integer>();
11         l1.add("Hello World");
12         l2.add(15);
13         read(l1);
14         read(l2);
15     }
16     public static void read(List<?> list) {
17         for (Object o : list) {
18             System.out.println(o);
19         }
20     }

 

    添加(写入):对于List<?>就不能向其内部添加数据。除了添加null之外。

    获取(读取):允许读取数据,读取的数据类型为Object。

  5、通配符的使用:注意点

    (1)编译错误:不能用在泛型方法声明上,返回值类型前面<>不能使用?

public static <?> void test(ArrayList<?> list){}

    

    (2)编译错误:不能用在泛型类的声明上

class GenericTypeClass<?>{}

    

    (3)编译错误:不能用在创建对象上,右边属于创建集合对象

ArrayList<?> list2 = new ArrayList<?>();

  

 

三、有限制的通配符

四、

五、

操作 Java 泛型(三):泛型在继承方面体现与通配符使用

原文:https://www.cnblogs.com/niujifei/p/14801482.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!