亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Eclipse3.1中體驗J2SE5.0之泛型

系統 1798 0

泛型(Generics)簡介

  J2SE 5.0中的最顯著的變化之一是添加對泛型類型的支持. 在J2SE 1.4 以及之前的版本中, Java程序并不是類型安全的. 例如, Collection framework中定義的List, Map等容器類的元素都是Object類型, 即這個類包含的元素是Object對象. 使用這種方式實現的列表, 可以用來操作整數, 實數, 字符串或者任何對象類型. 例如

清單1.1 類型不安全的代碼示例

            
              
List stringList = new ArrayList();
stringList.add("abcde");
String str = (String)stringList.get(0);

            
          

  這種方法實現的列表需要使用強制類型轉換(又稱顯示造型), 因此不是類型安全的. 在上面這段代碼種, 雖然變量名為stringList, 但是我們仍然可以把一個整型對象添加到這個隊列中, 例如,

清單1.2 類型不安全的代碼示例

            
              
stringList.add(new Integer(5));

            
          

  在這種情況下, 從字符列表中獲取對象時, 強制類型轉換就會導致運行時 異常 .

清單1.3 類型不安全的代碼示例

            
              
String str = (String)stringList.get(1); //runtime exception

            
          

  泛型是Java邁向類型安全的一個重要步驟, 使用泛型可以 構造 出類型安全的代碼.

聲明泛型

  所謂泛型是指類型參數化(parameterized types). Java是一種強類型的語言, 在J2SE 1.4以及以前的版本中, 我們在定義一個Java類, 接口或者方法的時候, 必須指定變量的類型. 在聲明泛型類、接口或者函數時, 定義變量的時候不指定某些變量的具體類型, 而是用一個類型參數代替. 在使用這個類, 接口, 或者方法的時候, 這個類型參數由一個具體類型所代替.

2.1 泛型類

  下面的例子中介紹了如何創建一個最簡單泛型類

清單2.1, 最簡單的泛型類

            
              
public class GenSample<T> {}

            
          

  類名后面帶有<T>表明了這個類是泛型類, 其中T被成為類型參數(type parameter), 在使用泛型的時候, 類型參數可以被替換為任何的類類型, 但是不能是原始類型(primitive type), 例如int, double.

  下面通過一個列表的例子來具體說明如果聲明泛型類和類型參數的用法.

清單2.2, 泛型列表

            
              
public class GenList <T>{
	private T[] elements;
	private int size = 0;
	private int length = 0;

	public GenList(int size) {
		elements = (T[])new Object[size];
		this.size = size;
	}

	public T get(int i) {
		if (i < length) {
			return elements[i];
		}
		return null;
	}
	
	public void add(T e) {
		if (length < size - 1)
			elements[length++] = e;
	}
}

            
          

  在列表的例子中, 類型參數T被用來表示列表中的元素的類型, 即, 這個列表中的元素是T類型的.

  在使用這個列表時, 這個類型參數T會被具體的類型所替代.

  注意, 由于T時類型參數不是具體的類, 所以不能使用new操作符創建T的對象,例如new T(), 或者, new T[10].

2.2 泛型接口

  在J2SE 5.0中, 不僅僅可以聲明泛型類, 也可以聲明泛型接口, 聲明泛型接口和聲明泛型類的語法類似, 也是在接口命稱后面加上<T>. 例如,

清單3.2.3, 泛型接口
            
              
public interface GenInterface<T> {
    void func(T t);
}

            
          

2.3、聲明多個類型參數的泛型類或者接口

  在聲明泛型類的時候, 可是使用多個類型參數. 多個類型參數之間用逗號分開, 例如,

清單3.2.4, 多個類型參數的泛型類
            
              
public class GenMap<T, V> {}

            
          

Eclipse 3.1的類創建向導支持創建泛型類, 如下圖所示,

圖2.1 使用類向導創建泛型類

圖3.2.1 使用類向導創建范型類

  使用Eclipse接口向導創建泛型接口

圖2.2 使用接口向導創建泛型接口
圖3.2.2 使用接口向導創建范型接口

  2.4 泛型方法

  類型參數(type parameter)不僅僅可以用來聲明泛型類或者泛型接口, 也可以用來聲明泛型方法, 而且這種聲明的泛型方法可以用在非泛型類中, 聲明泛型方法的一般格式是

清單2.5 泛型方法的一般形式
            
              
<type-list> return-type method-name(parameter-list) {}

            
          

清單3.2.6 泛型方法示例
            
              
public <T> String getString(T obj) {
	return obj.toString();
}

            
          

  2.5 受限泛型

  受限泛型是指類型參數的取值范圍是受到限制的. extends關鍵字不僅僅可以用來聲明類的繼承關系, 也可以用來聲明類型參數(type parameter)的受限關系.例如, 我們只需要一個存放數字的列表, 包括整數(Long, Integer, Short), 實數(Double, Float), 不能用來存放其他類型, 例如字符串(String), 也就是說, 要把類型參數T的取值泛型限制在Number極其子類中.在這種情況下, 我們就可以使用extends關鍵字把類型參數(type parameter)限制為數字,

清單2.7 受限泛型示例
            
              public class Limited<T extends Number> {
	public static void main(String[] args) {
		Limited<Integer> number;   //正確
		Limited<String> str;       //編譯錯誤
	}
}

            
          

  在Eclipse 3.1中, 上例中的編譯錯誤信息如下圖所示

圖2.3 由于受限泛型導致的編譯錯誤

圖3.2.3 由于受限范型導致的編譯錯誤

在程序中使用泛型

3.1在程序中使用泛型類

  在創建泛型類的對象的時候, 和創建普通對象基本類似, 必須提供具體的類類型來替代類型參數T (J2SE 5.0目前不支持原始類型作為類型參數(type parameter)).

清單3.1, 使用泛型類
            
              
//如果需要整型的列表
GenList<Integer> integerList = new GenList<Integer>();
//如果需要字符型的列表
GenList<String> strList = new GenList<String>();
//不能使用原始類型
GenList<int> nList = new GenList<int>();  //編譯錯誤

            
          

3.2 使用泛型解決類型安全性問題

  使用泛型實現的列表是類型安全的, 下列破壞類型安全語句會在編譯的時候檢查出來。 把鼠標放在錯誤標記上, Eclipse 3.1中的錯誤提示就會顯示,如下圖所示:

圖3.3.2 破壞類型安全引起的錯誤
圖3.3.2 破壞類型安全引起的錯誤

3.3 二義性錯誤

  GenMap在聲明是使用了2個類型參數T和V, 因此在創建GenMap的對象的時候也需要提供2個具體的類類型來替代這2個類型參數, 例如,

清單9, 多個參數的泛型類
            
              
GenMap<Integer, String> 
              
                gm
              
               = new GenMap<Integer, String>();
GenMap<String, String> gm2 = new GenMap<String, String>();

            
          

  上例中, T和V雖然看起來是兩個不同的類型參數, 但是在使用這個泛型類的時候, T和V很有可能被替換成同一種類型. 因此在聲明多個類型參數的泛型類時, 要注意避免這種二義性錯誤, 例如,

清單10, 二義性錯誤
            
              
public class GenMap<T, V> {
    //編譯錯誤, 二義性錯誤
    public void set(T t){}
    public void set(V v){}
}

            
          

  在上面這段代碼, 如果T和V被替換成同一種類型, set函數的 簽名 (signature)就是完全一樣的, 所以編譯器會報告二義性錯誤. 正確的用法是聲明2個不同名的方法, 例如,

清單10, 二義性錯誤
            
              
public class GenMap<T, V> {
    public void setKey(T t){}
    public void setValue(V v){}
}

            
          

圖3.3 二義性錯誤
圖3.3.3 二義性錯誤

3.4 使用通配符

  前面我們創建了泛型的列表, 如果我需要一個方法來處理泛型列表, 例如, 我們希望把列表中的每個元素都打印出來, 但是類型參數(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){}

            
          

  J2SE 5.0中提供了泛型的通配符"?", "?"可以用來代替任何類型, 例如使用通配符來實現print方法。

            
              
public static void print(GenList<?> list) {}

            
          

泛型的一些局限型

  (1) 類型參數不能實例化, 例如,

            
              
T t= new T();   //編譯錯誤

            
          

  (2) 不能實例化類型參數的數組

            
              
T[] ts= new T[10];   //編譯錯誤

            
          

  (3) 類的靜態變量不能聲明為類型參數類型

            
              
public class GenClass<T> {
     private static T t;    //編譯錯誤
}

            
          

  (4) 泛型類不能繼承自Throwable以及其子類

            
              
public GenExpection<T> extends Exception{}    //編譯錯誤

            
          

泛型小結

  泛型是J2SE 5.0所提供的一項強大的功能, 使用泛型可以創建類型安全的、可重用的代碼, 雖然目前Java的泛型還無法和C++的泛型相提并論, 但是, 隨著Java語言本事的演進, 泛型會在Java語言中發揮更大的作用的.

Eclipse3.1中體驗J2SE5.0之泛型


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久99热精品免费观看 | 欧美在线观看视频网站 | 夜夜骑狠狠干 | 国产21区| 猫咪www免费人成在线观看网址 | 午夜国产精品影院在线观看 | 欧美乱淫视频 | 高清人人天天夜夜曰狠狠狠狠 | 免费久久精品 | 亚洲乱码一区二区三区在线观看 | 久久天天躁狠狠躁夜夜不卡 | 欧美日韩不卡视频 | 久草在线视频中文 | 精品一区二区久久久久久久网站 | 久久久久久久亚洲精品一区 | 亚洲高清在线观看视频 | 久久精品看片 | 久久国产乱子伦精品免费看 | 国产91在线播放边 | 免费欧美黄色网址 | 亚洲天堂久久新 | 欧美日韩高清一区二区三区 | 国产成人久久精品激情 | 日本一区二区网站 | 亚洲一区二区三区精品国产 | 日韩成人综合网 | 毛片机地 | 国产在线视频福利 | 精品视频在线观看一区二区 | 国产免费美女视频 | 日韩毛片高清免费 | 女人18毛片一级毛片在线 | 日韩中文字幕久久精品 | 亚洲另类图 | 亚洲精品福利一区二区三区 | 9久热久re爱免费精品视频 | 国产日韩视频 | 日本一二区视频 | 午夜aaaaaaaaa视频在线 | 久久久www成人免费精品 | 在线毛片免费观看 |