00080_泛型

1、泛型的引入

  集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。比如下面程序:

 1   public class GenericDemo {
 2       public static void main(String[] args) {
 3         List list = new ArrayList();
 4         list.add("abc");
 5         list.add("love");
 6         list.add(5);//由于集合没有做任何限定,任何类型都可以给其中存放
 7                     //相当于:Object obj=new Integer(5);
 8         
 9         Iterator it = list.iterator();
10         while(it.hasNext()){
11           //需要打印每个字符串的长度,就要把迭代出来的对象转成String类型
12           String str = (String) it.next();//String str=(String)obj;
13                                           //编译时期仅检查语法错误,String是Object的儿子可以向下转型
14                                           //运行时期String str=(String)(new Integer(5))
15                                           //String与Integer没有父子关系所以转换失败
16                                           //程序在运行时发生了问题java.lang.ClassCastException
17           System.out.println(str.length());
18         }
19       }
20     }

2、泛型的定义和使用

 1 /*
 2      * JDK1.5 出现新的安全机制,保证程序的安全性
 3      *   泛型: 指明了集合中存储数据的类型  <数据类型>
 4      */
 5 
 6     public class GenericDemo {
 7       public static void main(String[] args) {
 8         function();
 9       }
10       
11       public static void function(){
12         Collection<String> coll = new ArrayList<String>();
13         coll.add("abc");
14         coll.add("rtyg");
15         coll.add("43rt5yhju");
16     //    coll.add(1);
17         
18         Iterator<String> it = coll.iterator();
19         while(it.hasNext()){
20           String s = it.next();
21           System.out.println(s.length());
22         }
23       }
24     }

3、Java中的伪泛型

  泛型只在编译时存在,编译后就被擦除,在编译之前我们就可以限制集合的类型,起到作用。例如:

ArrayList<String> al=new ArrayList<String>();

   编译后:

ArrayList al=new ArrayList();

4、泛型类

  (1)定义格式 

      修饰符 class 类名<代表泛型的变量> {  }
      例如,API中的ArrayList集合:
      class ArrayList<E>{ 
           public boolean add(E e){ }
        public E get(int index){  }
      }

  (2)使用格式

 创建对象时,确定泛型的类型
     
      例如,ArrayList<String> list = new ArrayList<String>();
      此时,变量E的值就是String类型
      class ArrayList<String>{ 
        public boolean add(String e){ }
        public String get(int index){  }
      }
     
      例如,ArrayList<Integer> list = new ArrayList<Integer>();
      此时,变量E的值就是Integer类型
      class ArrayList<Integer>{ 
           public boolean add(Integer e){ }
           public Integer get(int index){  }
      }

5、泛型的方法

  (1)定义格式

修饰符 <代表泛型的变量> 返回值类型 方法名(参数){  }

  (2)泛型方法的使用

例如,API中的ArrayList集合中的方法:
      public <T> T[] toArray(T[] a){  } 
      //该方法,用来把集合元素存储到指定数据类型的数组中,返回已存储集合元素的数组

      使用格式:调用方法时,确定泛型的类型
     例如:
          ArrayList<String> list = new ArrayList<String>();
          String[] arr = new String[100];
          String[] result = list.toArray(arr);
       此时,变量T的值就是String类型。变量T,可以与定义集合的泛型不同
       public <String> String[] toArray(String[] a){  } 
    

      例如:
          ArrayList<String> list = new ArrayList<String>();
          Integer[] arr = new Integer[100];
          Integer [] result = list.toArray(arr);
      
      此时,变量T的值就是Integer类型。变量T,可以与定义集合的泛型不同
      public <Integer> Integer[] toArray(Integer[] a){  } 

6、泛型的接口

 1 /*
 2       *  带有泛型的接口
 3       *  
 4       *  public interface List <E>{
 5       *    abstract boolean add(E e);
 6       *  }
 7       * 
 8       *  实现类,先实现接口,不理会泛型
 9       *  public class ArrayList<E> implements List<E>{
10       *  }
11       *  调用者 : new ArrayList<String>() 后期创建集合对象的时候,指定数据类型
12       *  
13       *  
14       *  实现类,实现接口的同时,也指定了数据类型
15       *  public class XXX implements List<String>{
16       *  }
17       *  new XXX()
18       */
19      public class GenericDemo2 {
20       
21      }

7、泛型的好处

  (1)将运行时期的ClassCastException,转移到了编译时期变成了编译失败;

  (2)避免了类型强转的麻烦。

 1 public class GenericDemo {
 2       public static void main(String[] args) {
 3         List<String> list = new ArrayList<String>();
 4         list.add("abc");
 5         list.add("love");
 6         //list.add(5);//当集合明确类型后,存放类型不一致就会编译报错
 7                      //集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型
 8        
 9         Iterator<String> it = list.iterator();
10         while(it.hasNext()){
11            String str = it.next();
12            System.out.println(str.length()); //当使用Iterator<String>      
13                                             //控制元素类型后,就不需要强转了。获取到的元素直接就是String类型
14         }
15       }
16     }

8、泛型的通配符

 1 /*
 2     *  泛型的通配符
 3     */
 4    public class GenericDemo {
 5     public static void main(String[] args) {
 6       ArrayList<String> array = new ArrayList<String>();
 7       
 8       HashSet<Integer> set = new HashSet<Integer>();
 9       
10       array.add("123");
11       array.add("456");
12       
13       set.add(789);
14       set.add(890);
15       
16       iterator(array);
17       iterator(set);
18     }
19     /*
20      *  定义方法,可以同时迭代2个集合
21      *  参数: 怎么实现 , 不能写ArrayList,也不能写HashSet
22      *  参数: 或者共同实现的接口
23      *  泛型的通配,匹配所有的数据类型  ?
24      */
25     public static void iterator(Collection<?> coll){
26       Iterator<?> it = coll.iterator();
27       while(it.hasNext()){
28         //it.next()获取的对象,什么类型
29         System.out.println(it.next());
30       }
31     }
32    }

9、泛型的限定

 1 /*
 2     *  将的酒店员工,厨师,服务员,经理,分别存储到3个集合中
 3     *  定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法
 4     */
 5    import java.util.ArrayList;
 6    import java.util.Iterator;
 7    public class GenericTest {
 8     public static void main(String[] args) {
 9       //创建3个集合对象
10       ArrayList<ChuShi> cs = new ArrayList<ChuShi>();
11       ArrayList<FuWuYuan> fwy = new ArrayList<FuWuYuan>();
12       ArrayList<JingLi> jl = new ArrayList<JingLi>();
13       
14       //每个集合存储自己的元素
15       cs.add(new ChuShi("张三", "后厨001"));
16       cs.add(new ChuShi("李四", "后厨002"));
17       
18       fwy.add(new FuWuYuan("翠花", "服务部001"));
19       fwy.add(new FuWuYuan("酸菜", "服务部002"));
20       
21       jl.add(new JingLi("小名", "董事会001", 123456789.32));
22       jl.add(new JingLi("小强", "董事会002", 123456789.33));
23       
24    //   ArrayList<String> arrayString = new ArrayList<String>();
25       iterator(jl);
26       iterator(fwy);
27       iterator(cs);
28     
29     }
30     /*
31      * 定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法 work
32      * ? 通配符,迭代器it.next()方法取出来的是Object类型,怎么调用work方法
33      * 强制转换:  it.next()=Object o ==> Employee
34      * 方法参数: 控制,可以传递Employee对象,也可以传递Employee的子类的对象
35      * 泛型的限定  本案例,父类固定Employee,但是子类可以无限?
36      *   ? extends Employee 限制的是父类, 上限限定, 可以传递Employee,传递他的子类对象
37      *   ? super   Employee 限制的是子类, 下限限定, 可以传递Employee,传递他的父类对象
38      */
39     public static void iterator(ArrayList<? extends Employee> array){
40       
41        Iterator<? extends Employee> it = array.iterator();
42        while(it.hasNext()){
43          //获取出的next() 数据类型,是什么Employee
44          Employee e = it.next();
45          e.work();
46        }
47     }
48    }
原文地址:https://www.cnblogs.com/gzdlh/p/8093659.html