歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java 泛型編程詳解

Technorati 標記: java,泛型,generic

java泛型應用是java核心基礎之一,從java 5開始引進泛型。如果你曾經使用過java Collection,那你已經算是接觸過泛型了。在java Collection裡使用泛型是一件很簡單的事情,可泛型還具有很多你意想不到的作用。在深入了解泛型之前,首先來了解一下泛型的一些基本概念與原理。

一、java 泛型引入

java泛型的應用可以提高的代碼的復用性,同時泛型提供了類型檢查,減少了數據的類型轉換,同時保證了類型安全。下面看一下,泛型如何保證了類型安全:
List list = new ArrayList();
list.add("abc");
list.add(new Integer(1)); //可以通過編譯
for (Object object : list) {
 System.out.println((String)object);//拋出ClassCastException異常
}
    上面的代碼會在運行時拋出ClassCastException,因為它嘗試將一個Integer轉換為String。接著,來看一下從java5開始,Collection的用法:
List<String> list = new ArrayList<>();
list.add("abc");
//list.add(new Integer(1)); //編譯錯誤
for (String string : list) {
 System.out.println(string);//無需任何強制類型轉換
}
    注意到,List的創建增加了類型參數String,因此只能向list添加String類型對象,添加其他對象會拋出編譯異常;同樣可以注意到,foreach循環不需要再添加任何強制類型轉換,也就移除了運行時的ClassCastException異常。
二、泛型的類與接口
    既然是學泛型,自然就要知道如何去使用泛型定義自己的類和接口。同時為了加深理解泛型的作用,先引進一個原始的類:
public class Gen {
 private Object obj;
 
 public Object getObj() {
  return obj;
 }

 public void setObj(Object obj) {
  this.obj = obj;
 }
 
 public static void main(String[] args) {
  Gen gen = new Gen();
  gen.setObj("abc");
  String str = (String) gen.getObj();//類型轉換,可能會引起運行時ClassCastException
 }
}
    原始類的定義,容易引發ClassCastException,和第一大點談到的類似。現在來看一下泛型類來重新定義Gen — 使用<>指定泛型參數,如下:
public class Gen<T> {
 T obj;

 public T getObj() {
  return obj;
 }

 public void setObj(T obj) {
  this.obj = obj;
 }
 public static void main(String[] args) {
  Gen<String> gen = new Gen<>();
  gen.setObj("abc");
//  gen.setObj(10);  //無法通過編譯
  String str = gen.getObj(); //無需類型轉換
  //-----------------------------
  Gen gen2 = new Gen();//raw type原始類型
  gen2.setObj("abc");
  gen2.setObj(10); //可以通過編譯,自動裝箱將10轉化為Integer對象
  Integer num = (Integer) gen2.getObj();//使用了強制類型轉換
 }
}    細心的你會發現在main()方法裡是使用泛型類型Gen<String>,便不再需要強制類型轉換,也就移除了運行時的ClassCastException。同時為了區別,在此也定義了一個沒有使用泛型類型的gen2,這時,編譯器會彈出一個警告“Gen is a raw type,References to generic type Gen<T> should be parameterized”。當我們不提供泛型類型時,會默認使用Object會代替,也是因此這樣,gen2可以設置String和Integer類型,不過,我們應盡量去避免這種這種情況的出現,如此,便又需要用到強制類型轉換,也伴隨著運行時的ClassCastException異常。
    tips:可以使用@SuppressWarnings("rawtypes")來抑制編譯器彈出警告。
    接口的泛型應用和類的泛型應用很類似,如下:
public interface List <E> {
  void add(E x);
  Iterator<E> iterator();
}

public interface Iterator<E> {
  E next();
  boolean hasNext();
}
    類似的,可以將此應用到自定義的接口與類當中。另外再提一下的是,可以使用多個泛型參數來定義接口與類,比如Map<K,V>;同時,泛型類型也可以作為一個參數來用,如下:new HashMap<String, List<String>>()。

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2013-10/90922p2.htm

Copyright © Linux教程網 All Rights Reserved