1) 一句话总结泛型的和核心。

就是类装载类型的参数化。类型是:比如ArrayList<E> , E已经参数化了。E已经是ArrayList中的一部分了,所以当

ArrayList<Boolean> list1 = new ArrayList<Boolean>();

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

list1=list2 ;

//会出现编译错误,因为Boolean 和 Integer已经是ArrayList中的一部分了。作用是不需要进行强制类型转换。

2)相关语法:

  • 可以加多个类型参数,用逗号隔开。比如 Generic<T,E>
  • 不能创建一个泛型数组。比如 T[] objectArr = new T[10] ; 语法上是不允许的。解决方式是new一个Object数组然后强行转换为T数组:T[] objectArr=(T[])new Object[10];
  • 当然T也可以是一个泛型,比如 ArrayList<E> E可以代表一个自己定义的泛型比如 Generic<T> 。所以叫做泛型中包括泛型。
  • JDK1.5中所有的集合类都重写为泛型了。

 

3)限制泛型中的引用类型。

定义泛型的类别是,默认情况下可以使用任何类来定义泛型中的类型。如ArrayList<T>,T可以是任何类型。当然也可以限制T类型,使用extends关键字来制这个类的装载类型。

实例化泛型的引用类别时(就是这个引用能够引用什么类别时),可以使用 ? 比如要实现下面的需求让ge1=ge2,

Generic<? extends List> ge1; Generic<? extends List> ge2 ;

ge1= new Generic<ArrayList>();

ge2=new Generic<LinkedList>();

这时候就可以使 ge1=ge2; 同时可以使用 <? super List> 表示List上面的类。

注意:在使用<?>或者<? extends Object>时这两个相同,意味着该引用只能通过赋值的方式(增加)或者通过删除的方式ge.set(null);但不能增加它的信息 比如ge.set(new ArrayList<String>()); 因为违反了泛型的初衷。

上面的总结可能比较含糊,看看代码和代码的注释就明白了。

 
  1. import java.util.ArrayList;  
  2. import java.util.LinkedList;  
  3. import java.util.List;  
  4.    
  5. public class TestGeneric<t> {  
  6.     private  T  foo ;   
  7.    
  8.     public T getFoo() {  
  9.         return foo;  
  10.     }  
  11.    
  12.     public void setFoo(T foo) {  
  13.         this.foo = foo;  
  14.     }  
  15.    
  16.     public static  void main(String... args){  
  17.    
  18. //       在类声明时上面的T表示这个类可以装载什么类型  如果类名改变为 TestGeneric<t extends="" list=""> 
  19. //      说明只能装载List的子类别   
  20.    
  21. //      而TestGeneric<?> 则表明了 这个类的引用可以指向什么样的类型,看下面的例子  
  22. //      如果是这样的话就会报错,因为ge只能指向 TestGeneric<ArrayList>()  
  23. //      TestGeneric<ArrayList> ge=  new TestGeneric<ArrayList>();  
  24. //      ge = new TestGeneric<LinkedList>();  
  25.    
  26.         //但是如果这样ge就可以指向TestGeneric<ArrayList> 和TestGeneric<LinkedList>和  
  27.         //TestGeneric<Object>(); 以及任何Object的子类  
  28.         TestGeneric<?> genew TestGeneric<arraylist>();  
  29.         genew TestGeneric  
  30. <linkedlist>();  
  31.         ge = new TestGeneric<object>();  
  32.    
  33.         //但是如果只想指向实现了List接口的类,可以使用 <? extends List> 
  34.         TestGeneric<? extends List> ge1new TestGeneric<ArrayList>();  
  35.         ge1 =  new TestGeneric<LinkedList>();  
  36. //      ge1 =  new TestGeneric<Object>();   会报错  
  37.    
  38. //      同时还可以指定引用的父类,说明ge2只能指向TestGeneric所装载的类的List的上层类别  
  39.         TestGeneric<? super List> ge2 = new TestGeneric<Object>();  
  40.    
  41.         //关于赋值  
  42.         TestGeneric<String>  ge3 = new TestGeneric<String>();  
  43.         ge3.setFoo("Hello World.....");  
  44.    
  45.         TestGeneric<?>  ge4 = new TestGeneric<string>();  
  46.         ge4=ge3;  
  47.         ge3.getFoo();  //是正确的  
  48. //      ge4.setFoo("String");  但是set就会编译错误,因为ge4.set(?) 是一个问号类型,这样当  
  49. //      get的时候就会不知道其明确的类型,这违反了 泛型的初衷  
  50.    
  51.     }  
  52. }  
  53. </string></object></linkedlist></arraylist></t></t>