熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Eclipse3.1中體驗J2SE5.0之泛型(組圖)

2022-06-13   來源: Java開源技術 

  泛型(Generics)簡介
  
  JSE 中的最顯著的變化之一是添加對泛型類型的支持 在JSE 以及之前的版本中 Java程序並不是類型安全的 例如 Collection framework中定義的List Map等容器類的元素都是Object類型 即這個類包含的元素是Object對象 使用這種方式實現的列表 可以用來操作整數 實數 字符串或者任何對象類型 例如
  
  清單 類型不安全的代碼示例
  
  List stringList = new ArrayList();
  stringListadd(abcde);
  String str = (String)stringListget();
  
  這種方法實現的列表需要使用強制類型轉換(又稱顯示造型) 因此不是類型安全的 在上面這段代碼種 雖然變量名為stringList 但是我們仍然可以把一個整型對象添加到這個隊列中 例如
  
  清單 類型不安全的代碼示例
  
  stringListadd(new Integer());
  
  在這種情況下 從字符列表中獲取對象時 強制類型轉換就會導致運行時異常
  
  清單 類型不安全的代碼示例
  
  String str = (String)stringListget(); //runtime exception
  
  泛型是Java邁向類型安全的一個重要步驟 使用泛型可以構造出類型安全的代碼
  
  聲明泛型
  
  所謂泛型是指類型參數化(parameterized types) Java是一種強類型的語言 在JSE 以及以前的版本中 我們在定義一個Java類 接口或者方法的時候 必須指定變量的類型 在聲明泛型類接口或者函數時 定義變量的時候不指定某些變量的具體類型 而是用一個類型參數代替 在使用這個類 接口 或者方法的時候 這個類型參數由一個具體類型所代替
  
   泛型類
  
  下面的例子中介紹了如何創建一個最簡單泛型類
  
  清單 最簡單的泛型類
  
  public class GenSample<T> {}
  
  類名後面帶有<T>表明了這個類是泛型類 其中T被成為類型參數(type parameter) 在使用泛型的時候 類型參數可以被替換為任何的類類型 但是不能是原始類型(primitive type) 例如int double
  
  下面通過一個列表的例子來具體說明如果聲明泛型類和類型參數的用法
  
  清單 泛型列表
  
  public class GenList <T>{
  private T[] elements;
  private int size = ;
  private int length = ;
  
  public GenList(int size) {
  elements = (T[])new Object[size];
  thissize = size;
  }
  
  public T get(int i) {
  if (i < length) {
  return elements[i];
  }
  return null;
  }
  
  public void add(T e) {
  if (length < size )
  elements[length++] = e;
  }
  }
  
  在列表的例子中 類型參數T被用來表示列表中的元素的類型 這個列表中的元素是T類型的
  
  在使用這個列表時 這個類型參數T會被具體的類型所替代
  
  注意 由於T時類型參數不是具體的類 所以不能使用new操作符創建T的對象例如new T() 或者 new T[]
  
   泛型接口
  
  在JSE 不僅僅可以聲明泛型類 也可以聲明泛型接口 聲明泛型接口和聲明泛型類的語法類似 也是在接口命稱後面加上<T> 例如
  
  清單 泛型接口
  
  public interface GenInterface<T> {
  void func(T t);
  }
  
  聲明多個類型參數的泛型類或者接口
  
  在聲明泛型類的時候 可是使用多個類型參數 多個類型參數之間用逗號分開 例如
  
  清單 多個類型參數的泛型類
  
  public class GenMap<T V> {}
  
  Eclipse 的類創建向導支持創建泛型類 如下圖所示
  
  圖 使用類向導創建泛型類
  
 educitycn/img_///jpg >

  使用Eclipse接口向導創建泛型接口
  
  圖 使用接口向導創建泛型接口
  
 educitycn/img_///jpg >

   泛型方法
  
  類型參數(type parameter)不僅僅可以用來聲明泛型類或者泛型接口 也可以用來聲明泛型方法 而且這種聲明的泛型方法可以用在非泛型類中 聲明泛型方法的一般格式是
  
  清單 泛型方法的一般形式
  
  <typelist> returntype methodname(parameterlist) {}
  
  清單 泛型方法示例
  
  public <T> String getString(T obj) {
  return objtoString();
  }
  
   受限泛型
  
  受限泛型是指類型參數的取值范圍是受到限制的 extends關鍵字不僅僅可以用來聲明類的繼承關系 也可以用來聲明類型參數(type parameter)的受限關系例如 我們只需要一個存放數字的列表 包括整數(Long Integer Short) 實數(Double Float) 不能用來存放其他類型 例如字符串(String) 也就是說 要把類型參數T的取值泛型限制在Number極其子類中在這種情況下 我們就可以使用extends關鍵字把類型參數(type parameter)限制為數字
  
  清單 受限泛型示例
  public class Limited<T extends Number> {
  public static void main(String[] args) {
  Limited<Integer> number;  //正確
  Limited<String> str;    //編譯錯誤
  }
  }
  
  在Eclipse 上例中的編譯錯誤信息如下圖所示
  
  圖 由於受限泛型導致的編譯錯誤
  
 educitycn/img_///jpg >

  在程序中使用泛型
  
  在程序中使用泛型類
  
  在創建泛型類的對象的時候 和創建普通對象基本類似 必須提供具體的類類型來替代類型參數T (JSE 目前不支持原始類型作為類型參數(type parameter))
  
  清單 使用泛型類
  
  //如果需要整型的列表
  GenList<Integer> integerList = new GenList<Integer>();
  //如果需要字符型的列表
  GenList<String> strList = new GenList<String>();
  //不能使用原始類型
  GenList<int> nList = new GenList<int>(); //編譯錯誤
  
   使用泛型解決類型安全性問題
  
  使用泛型實現的列表是類型安全的 下列破壞類型安全語句會在編譯的時候檢查出來 把鼠標放在錯誤標記上 Eclipse 中的錯誤提示就會顯示如下圖所示
  
  圖 破壞類型安全引起的錯誤
  
 educitycn/img_///jpg >

   二義性錯誤
  
  GenMap在聲明是使用了個類型參數T和V 因此在創建GenMap的對象的時候也需要提供個具體的類類型來替代這個類型參數 例如
  
  清單 多個參數的泛型類
  
  GenMap<Integer String> gm = new GenMap<Integer String>();
  GenMap<String String> gm = new GenMap<String String>();
  
  上例中 T和V雖然看起來是兩個不同的類型參數 但是在使用這個泛型類的時候 T和V很有可能被替換成同一種類型 因此在聲明多個類型參數的泛型類時 要注意避免這種二義性錯誤 例如
  
  清單 二義性錯誤
  
  public class GenMap<T V> {
  //編譯錯誤 二義性錯誤
  public void set(T t){}
  public void set(V v){}
  }
  
  在上面這段代碼 如果T和V被替換成同一種類型 set函數的簽名(signature)就是完全一樣的 所以編譯器會報告二義性錯誤 正確的用法是聲明個不同名的方法 例如
  
  清單 二義性錯誤
  
  public class GenMap<T V> {
  public void setKey(T t){}
  public void setValue(V v){}
  }
  
  圖 二義性錯誤
  
educitycn/img_///jpg >

   使用通配符
  
  前面我們創建了泛型的列表 如果我需要一個方法來處理泛型列表 例如 我們希望把列表中的每個元素都打印出來 但是類型參數(type parameter)只能使用在聲明一個泛型類的時候 如果類型參數使用在函數定義裡會導致編譯錯誤
  
  public static void print(GenList<T> list){} //編譯錯誤
  
  在這種情況下 我們需要用另外一種方法來表示一個泛型類 否則 就可能需要書寫多個print函數
  
  public static void print(GenList<Integer> list){}
  public static void print(GenList<Double> list){}
  …
  public static void print(GenList<String> list){}
  
  JSE 中提供了泛型的通配符? ?可以用來代替任何類型 例如使用通配符來實現print方法
  
  public static void print(GenList<?> list) {}
  
  泛型的一些局限型
  
  () 類型參數不能實例化 例如
  
  T t= new T();  //編譯錯誤
  
  () 不能實例化類型參數的數組
  
  T[] ts= new T[];  //編譯錯誤
  
  () 類的靜態變量不能聲明為類型參數類型
  
  public
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28091.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.