java泛型探索——介紹篇

來源:互聯網
上載者:User

標籤:world   nts   引入   tor   定義   collect   是什麼   for   sys   

1. 泛型出現前後代碼對比 

 先來看看泛型出現前,代碼是這麼寫的:

List words = new ArrayList();words.add("Hello ");words.add("worlds!");String s = (String) words.get(0) + (String) words.get(1);System.out.println(s.equals("Hello worlds!"));

 而泛型出現後無需做顯式轉換:

words.add("Hello ");words.add("worlds!");String s = words.get(0) + words.get(1);System.out.println(s.equals("Hello worlds!"));

 從本質上來說,以上代碼編譯為位元組碼後是一樣的,對JVM而言沒有區別。

2. 為什麼有泛型?

 泛型是什嗎?  

 泛型允許程式員編寫代碼時使用一些以後才指定的類型,允許在定義類和介面的時候使用型別參數,java泛型的參數只可以代表類,不能代表個別對象。

 泛型的引入可以解決之前的集合類架構在使用過程中通常會出現的運行時刻類型錯誤[1]。

interface Iterator<E> {    public boolean hasNext();    public E next();    public void remove();        ...}

泛型方法也可以哦:

class List {    public static<T> List<T> toList(T[] arr) {        List<T> list = new ArrayList<T>();        for (T elt : arr) list.add(elt);        return list;    }}

為什麼有泛型? 

 1) 泛型可以隱式地執行類型轉換,並且永遠不會失敗(cast-iron guarantee[2]):

1 List<String> words = new ArrayList<String>();2 由於泛型的類型擦除特性,所有添加到words中的變數,都會被轉換為Object,3 此時就需要泛型的類型轉換特性,在執行words.get(i)時做強制轉換。

 2) 泛型由於類型擦除特性(後面的章節介紹),如List<Integer>,List<String>,List<Number>編譯成位元組碼是一樣的,

 而不是每一個都有一個版本,保持著簡潔性。

 3) 最後也是最後要的一點:泛型的相容性,可相容jdk1.4以前的版本。從JVM的角度看,由於泛型代碼編譯成位元組碼與jdk1.4

 之前的代碼無任何差別,因此可以很容易的修改jdk1.4寫的函數庫中的某一個函數,而無需修改整個函數庫。

3. 泛型萬用字元

 首先以一個樣本講解為什麼需要泛型萬用字元,如果我們定義addAll方法如下所示: 

interface Collection<E> {...    public boolean addAll(Collection<E> c);...}/**  **測試代碼**/List<Number> nums = new ArrayList<Number>();List<Integer> ints = Arrays.asList(1,2,3);nums.addAll(ints); // 編譯錯誤

 如果我們想在List<Number>中添加List<Integer>怎麼辦呢?這是就需要使用萬用字元了。

interface Collection<E> {...    public boolean addAll(Collection<? extends E> c);...}/**  **測試代碼**/List<Number> nums = new ArrayList<Number>();List<Integer> ints = Arrays.asList(1,2,3);List<Double> dbls = Arrays.aslist(3.14,3.21);nums.addAll(ints); nums.addAll(dbls);

 從上述代碼可以看出,萬用字元的出現解決了泛型的子類問題:

 List<Integer>與List<Double>都是List<? extends Number>的子類;而不是  List<Number>的子類。

 最後,給出一個結論:當S是T的子類時,List<S>是List<?extends T>的子類;

 當S是T的超類時,List<S>是List<? super T>的子類。此外,List<?>是List<? extends Object>的縮寫。

接下來,我們分析萬用字元的重要的特性——put and get原則[2]。

 對extends而言,List<? extends T>只能get不能add或put。

List<Integer> ints = new ArrayList<Integer>();ints.add(1);ints.add(2);List<? extends Number> nums = ints;
System.out.println(nums.get(0)); // 編譯成功nums.add(3); // 編譯錯誤nums.add(3.14); // 編譯錯誤

 對於super而言,List<? super T>只能put或add,不能get。

List<Number> ints = new ArrayList<Number>();ints.add(1);ints.add(2);List<? super Integer> nums = ints;nums.add(3); 

 凡是都有例外,對於extends來說,List<? extends Number> nums可以add null,即nums.add(null);對於super來說,

 List<? super Integer> nums  可以get(取出)Object對象。

4. 參考文獻 

[1]  http://www.infoq.com/cn/articles/cf-java-generics

[2] java Generics and Collections

java泛型探索——介紹篇

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.