泛型

泛型:
      jdk5以前,对象保存到集合中就会失去其特性,取出时通常要程序员时行类型的强制转换,这样,不可避免就会引发程序的一些安全性问题。
如:
      ArrayList list = new ArrayList();
      list.add("aaa");
      Integer num = (Integer)list.get(0);  //运行时会出错,但编码时发现不了

      jdk5中的泛型允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生的问题,转变为编译时的问题,以提高程序的稳定性和可读性(尤其在大型程序中更为突出)。

      在使用泛型时泛型类型必须为引用类型,不能是基本数据类型。
      如果两边都使用了泛型,泛型的类型必须一致,但可以一边使用泛型,另一边不使用
      注:泛型是提供给javac编译器使用的,它用于限制集合的输入类型,让编译器在源代码级别上,挡住向集合中插入非法数据。但编译器编译完带有泛型的java程序后,生成的class文件不再带有泛型信息,以此使程序运行效率不受影响,这个过程称之为“擦除”。

泛型的基本术语

  • 以ArrayList<E>为例:<>读为“typeof”
  • ArrayList<E>中的E称为类型参数变量
  • ArrayList<Integer>中的Integer 称为实际类型参数
  • 整个ArrayList<E>称为泛型类型
  • 整个ArrayList<Integer>称为参数化的类型ParameterizedType

例1:基本泛型

 1 import java.util.ArrayList;
 2 import java.util.Iterator;
 3 import java.util.LinkedHashMap;
 4 import java.util.List;
 5 import java.util.Map;
 6 import java.util.Map.Entry;
 7 import java.util.Set;
 8 
 9 import org.junit.Test;
10 
11 public class GenericTest {
12 
13     @Test
14     public void test1(){
15         //下面操纵的list中的类型只能为String
16         List<String> list = new ArrayList<String>();
17         list.add("123");
18         System.out.println(list.get(0));
19     }
20     
21     @Test
22     public void test2(){
23         
24         Map<Integer, String> map = new LinkedHashMap<Integer, String>();
25         map.put(1, "A");
26         map.put(2, "B");
27         map.put(3, "C");
28         map.put(4, "D");
29         map.put(5, "E");
30         
31         Set<Entry<Integer,String>> entrySet = map.entrySet();
32         for (Entry<Integer, String> entry : entrySet) {
33             Integer key = entry.getKey();
34             String value = entry.getValue();
35             System.out.println(key + ":" + value);
36         }
37         
38         Set<Integer> keySet = map.keySet();
39         Iterator<Integer> iterator = keySet.iterator();
40         while(iterator.hasNext()){
41             Integer key = iterator.next();
42             System.out.println(key + ":" + map.get(key));
43         }
44     }
45 }

例2:自定义泛型

 1 public class GenericDemo {
 2 
 3     
 4     public void testMethod1(){
 5         testMethod("张三");
 6         testMethod(123);
 7     }
 8     
 9     /**
10      * 自定义带泛型的方法,如下:   -->自定义泛型,首先要先声明即<T> ,后边的(T t)为使用<T>这个泛型
11      * <T> 表示自定义的一个泛型,但未确切指定是什么类型,
12      * 在调用这个方法的时候,传入的参数是什么类型,则“T”表示的就是什么类型
13      * 如test1()中testMethod("张三")此时入参为String类型的,则“T”表示的类型就是String
14      *             testMethod(123)为Integer类型,则“T”表示的类型就为Integer
15      */
16     public <T> T testMethod(T t){
17         return null;
18     }
19     
20     /**
21      * 如下,多个泛型的方法
22      */
23     public <T,E,K> void testMethod2(T t,E e,K k){
24         
25     }
26 }
27 
28 /**
29  * 自定义类上的泛型
30  * 类上也可以声明泛型,作用范围就是整个类
31  */
32 class TestDemo<T>{
33     
34     public T test(){
35         return null;
36     }
37     public <E> void test1(T t,E e){
38         
39     }
40     
41     /**
42      * 静态的方法,不能够使用类上定义的泛型,如果使用必须得在静态方法上自定义,且在static之后
43      */
44     public static <T> void c(T t){
45         
46     }
47 }

例3:自定义泛型小例

 1 import org.junit.Test;
 2 
 3 public class GenericExample {
 4 
 5     @Test
 6     public void test1(){
 7         String[] arr = {"A","B","C","D","E","F"};
 8         genDemo(arr);
 9         Integer[] arrInt = {1,2,3,4,5,6,7};
10         genDemo(arrInt);
11     }
12     
13     
14     //用泛型写一个方法,将一数组中的元素反转过来
15     public <T> void genDemo(T arr[]){
16         int len = arr.length - 1;
17         int start = 0;
18         while(true){
19             if(start >= len){
20                 break;
21             }
22             T temp = arr[start];
23             arr[start] = arr[len];
24             arr[len] = temp;
25             start ++;
26             len --;
27         }
28         for (T t : arr) {
29             System.out.println(t);
30             //输出结果:FEDCBA7654321
31         }
32     }
33 }
原文地址:https://www.cnblogs.com/zunpeng/p/3387753.html