参考文章:http://www.infoq.com/cn/articles/cf-java-generics

1、Java泛型是Java5以后才出现的特性,主要是为了代码重用的同时在编译器来避免类型转换问题。泛型的存在的意义在于类型替换,和禁止一些可能出现类型转换问题的编码,在编译期就报错

2、Java源代码首先通过编译得到class字节码文件,然后在jvm中运行。java class文件中是不存在类型信息的,也就是说开始定义的泛型都会在编译后消失。这就是类型檫除,Java中的泛型基本上都是在编译器这个层面上实现的。例如

List和List等类型在编译之后都变成List。因此有以下几种特性:

(1)只存在List.class,而不存在List.class,List.class

(2)静态变量是由类的所有实例共享的,因此不能定义泛型的静态变量

   
   
   
   
  1. public class MyClass
  2.    private static T s;//编译错误 

(3)异常类是在运行时抛出,通过catch捕获,但是运行时类型信息被抹去,所以对于MyException和MyException对于catch来说无法分辨

3、编译期间,对于泛型T来说,先用object进行替换,如果利用extends定义了上界,那么就利用上界类进行替换。

4、通配符?和上下界extends、super

(1)通配符?表示类型未知,因此可以传入任意类型。从语法层面上规定了通配符指定的对象不能实例化,因为类型未知。例如new ArrayList()是错误的。下面例子中的alist.add(1)也是禁止的,因为List类型未知。试图对一个带通配符的泛型类进行操作都会出现编译错误。它和List的区别在于,即使是Object也是类型已知可以进行操作和实例化,所以下面代码中blist.add(1)是不会报错的。如果参数是List,传入List,虽然理解上是可以的,但是编译器为了避免出现blist.add(1)这种在String列表中加入Integer的行为导致的ClassCastException,所以禁止这样做。

(2)定义泛型后,就给原来的继承体系增加了一个维度。例如Collection ,List,Set和List,Set都是其子类,都可以作为匹配参数传入

下面的代码

   
   
   
   
  1. public class GenericTestextends Number> { 
  2.     public void get(List alist) { 
  3.         alist.get(0); 
  4.   alist.add(1);//?通配符,表示类型未定,编译器禁止add 
  5.     } 
  6.  
  7.     public void getO(List blist) { 
  8.   blist.add(1);//在该函数内部,list加入一个整型是没错的 
  9.     } 
  10.  
  11.     public void test() { 
  12.         get(new ArrayList());//正确 
  13.         get(new ArrayList());//正确 
  14.         getO(new ArrayList());//编译错误,因为可能会出现潜在的类型转换问题 
  15.     } 
  16. (3)?extends XX限定了?匹配的上界,只有XX及其子类可以通过匹配。其主要应用场景是可以get得到XX的引用,来调用XX指定的方法,但是不能直接add,因为传入的参数确定的类型是其子类,add父类是不行的

    (4)?super XX限定了?匹配的下界,只有XX及其父类可以通过匹配。其主要应用可以add加入XX的实例,因为XX是下界,传入的只能是XX及其父类,向上转型是可以的。但是不能get到XX的引用

       
       
       
       
    1. public class GenericTestextends Number> { 
    2.     
    3.     public void get1(Listextends B> alist) { 
    4.  
    5.     } 
    6.     public void get2(Listsuper B> alist) { 
    7.  
    8.     } 
    9.     public void test() { 
    10.         get1(new ArrayList());//编译错误,B或者其子类 
    11.         get1(new ArrayList()); 
    12.         get1(new ArrayList()); 
    13.         get2(new ArrayList()); 
    14.         get2(new ArrayList()); 
    15.         get2(new ArrayList());//编译错误,B或者其父类 
    16.     } 
    17.   
    18.  public void upperBound(Listextends Date> list, Date date)   
    19.  {   
    20.       Date now = list.get(0);   
    21.       System.out.println("now==>" + now);   
    22.      //list.add(date); //这句话无法编译   
    23.      list.add(null);//这句可以编译,因为null没有类型信息   
    24.  } 
    25.  //可能的调用导致上界约束的add方法错误 
    26.  public void testUpperBound()   
    27.  {   
    28.       List list = new ArrayList();   
    29.      Date date = new Date();   
    30.      upperBound(list,date);   
    31.  } 
    32.  public void lowerBound(Listsuper Timestamp> list)   
    33.  {   
    34.      Timestamp now = new Timestamp(System.currentTimeMillis());   
    35.      list.add(now);   
    36.       //Timestamp time = list.get(0); //不能编译   
    37.  }   
    38.  //可能的调用导致下界约束get方法错误 
    39.  public void testLowerBound()   
    40.  {   
    41.      List list = new ArrayList();   
    42.      list.add(new Date());   
    43.      lowerBound(list);   
    44.  }  
    45.  
    46. class A { 
    47.  
    48. class B extends A { 
    49.  
    50. class C extends B { 

    5、泛型方法:是否拥有泛型方法与是否在泛型类中无关,只需在返回值前加上就行

       
       
       
       
    1. public class GenericTest { 
    2.     public  List get(T t) { 
    3.         return new ArrayList(); 
    4.     } 
    5.  
    6.     public void test() { 
    7.         String s = ""
    8.         List list = get(s); 
    9.         list.add("tt"); 
    10.         list.add("ee"); 
    11.         for(String a:list){ 
    12.             System.out.println(a); 
    13.         } 
    14.     } 
    15.  
    16.     public static void main(String[] args) { 
    17.         GenericTest test=new GenericTest(); 
    18.         test.test(); 
    19.     } 

    第23条:请不要在新代码中使用原生态类型

    如果使用原生态类型,就失掉了泛型在安全性和表述性方面的所有优势

    你可能感兴趣的:(Java,泛型,Java)