Java 之泛型的應用

jopen 12年前發布 | 32K 次閱讀 Java Java開發

泛型(Generic)—泛形的作用

JDK5以前,對象保存到集合中就會失去其特性,取出時通常要程序員手工進行類型的強制轉換,這樣不可避免就會引發程序的一些安全性問題。例如:

ArrayList list = new ArrayList();

list.add("abc");

Integer num = (Integer) list.get(0);  //運行時會出錯,但編碼時發現不了

list.add(new Random());

list.add(new ArrayList());

for(int i=0;i

(?)list.get(i);          //此處取出來的對象應轉換成什么類型

}

Java 之泛型的應用

JDK5中的泛形允許程序員在編寫集合代碼時,就限制集合的處理類型,從而把原來程序運行時可能發生問題,轉變為編譯時的問題,以此提高程序的可讀性和穩定性(尤其在大型程序中更為突出)

注意:泛型是提供給javac編譯器使用的,它用于限定集合的輸入類型,讓編譯器在源代碼級別上,即擋住向集合中插入非法數據。但編譯器編譯完帶有泛形的java程序后,生成的class文件中將不再帶有泛形信息,以此使程序運行效率不受到影響,這個過程稱之為擦除

泛形的基本術語,以ArrayList為例:<>念著typeof

ArrayList中的E稱為類型參數變量

ArrayList中的Integer稱為實際類型參數

整個稱為ArrayList泛型類型

整個ArrayList稱為參數化的類型ParameterizedType 

泛型典型應用:

使用迭代器迭代泛形集合中的元素。

使用增強for循環迭代泛形集合中的元素。

存取HashMap中的元素。

//使用迭代器迭代泛型集合中的元素。

@Test

Public void test2(){

List list=new ArrayList();

 list.add(1);

 list.add(2);

 list.add(3);

Iterator it=list.iterator();

While (it.hasNext()){

System.out.println(it.next());

}

}

//使用增強for循環迭代泛型集合中的元素

@Test

Public void test3(){

List list=new ArrayList();

 list.add(1);

 list.add(2);

 list.add(3);

For(Integer  i:list){

System.out.println(i);

}

}

//存取HashMap中的元素。

@Test

Public void test4(){

Map map=new HashMap();

map.put(“key01”,1);

map.put(“key01”,1);

map.put(“key01”,1);

//(“key01”,1)看成一個Map.Entry

Set> set=map.entrySet();

For(Map.Entry en:set){

System.out.println(en.getKey()+”...”+en.getValue());

}

}

注意

使用泛形時的幾個常見問題:

使用泛形時,泛形類型須為引用類型,不能是基本數據類型

ArrayList list = new ArrayList ();  //

ArrayList list = new ArrayList(); //

ArrayList list = new ArrayList ();               //

ArrayList list = new ArrayList();               //

:使用泛型

        *  兩邊的類型必須一致

              ArrayList list = new ArrayList();

        *  兩邊只有一邊用泛型(為了保持兼容性)

              ArrayList list = new ArrayList ();

              ArrayList list = new ArrayList();

自定義泛形——泛型方法:

Java程序中的普通方法、構造方法和靜態方法中都可以使用泛型。方法使用泛形前,必須對泛形進行聲明,語法: T可以是任意字母,但通常必須要大寫。通常需放在方法的返回值聲明之前。例如:

public static  void method(T t);

注意:

只有對象類型才能作為泛型方法的實際參數。

在泛型中可以同時有多個類型,例如:編寫一個泛形方法,實現數組元素的交換。

Java 之泛型的應用

編寫一個泛形方法,接收一個任意數組,并顛倒數組中的所有元素

Java 之泛型的應用

如果一個類多處都要用到同一個泛型,這時可以把泛形定義在類上(即類級別的泛型),語法格式如下:

public class GenericDao {

private T field1;

public void save(T obj){}

public T getId(int id){}

}

注意

    *  在類級別上定義的泛型,只對類的非靜態成員有效

    *  靜態方法不能使用類定義的泛形,而應單獨定義泛形。

/*

 *  類級別泛型

 *  在類級別上定義的泛型,只對類的非靜態成員有效

 */

Public class DemoClass3{

Public void mathod1(T  t){

}

Public void mathod2(T  t){

}

//靜態方法不能使用類定義的泛型,而應單獨定義泛型

Public static  void method3(T  t){

}

}

泛形的典型應用:BaseDao

泛型的高級應用——通配符:

定義一個方法,接收一個集合,并打印出集合中的所有元素,如下所示:

void print (Collection c) {

           for (String e : c) {

                 System.out.println(e);

           }

問題:該方法只能打印保存了String對象的集合,不能打印其它集合。通配符用于解決此類問題,方法的定義可改寫為如下形式:

void print (Collection c)  {            //Collection(發音為:"collection of unknown") 

for (Object  e : c) {

System.out.println(e);

}

}

此種形式下需要注意的是:由于print方法c參數的類型為Collection,即表示一種不確定的類型,因此在方法體內不能調用與類型相關的方法,例如add()方法。

       但可以調用與類型無關的方法,例如size()方法

總結:使用?通配符主要用于引用對象,使用了?通配符,就只能調對象與類型無關的方法,不能調用對象與類型有關的方法。

Java 之泛型的應用

限定通配符的上邊界(?的類型必須是Number的子類)

限定通配符總是包括自己。

正確:Vector x = new Vector();

錯誤:Vector x = new Vector();

限定通配符的下邊界(?的類型必須是Integer的父類)

正確:Vector x = new Vector();

錯誤:Vector x = new Vector();

問題:以下代碼行不行?(如果是Byte類型不可以)

public void add(List list){

list.add(1000);

}

來自:http://blog.csdn.net/fengdongkun/article/details/8009230

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!