天天看點

泛型以及泛型怎麼實作總結?

http://www.cnblogs.com/lwbqqyumidi/p/3837629.html

http://www.cnblogs.com/fantasy01/p/3963593.html

http://www.importnew.com/19740.html

http://www.importnew.com/19740.html

1.泛型出現背景,解決問題:泛型可以把使用Object的錯誤提前到編譯階段,而不是運作階段,提升安全性。

1.當我們将一個對象放入集合中,集合不會記住此對象的類型,當再次從集合中取出此對象時,改對象的編譯類型變成了Object類型,但其運作時類型任然為其本身類型。

2.是以,//1處取出集合元素時需要人為的強制類型轉化到具體的目标類型,且很容易出現“java.lang.ClassCastException”異常。

那麼有沒有什麼辦法可以使集合能夠記住集合内元素各類型,且能夠達到隻要編譯時不出現問題,運作時就不會出現“java.lang.ClassCastException”異常呢?答案就是使用泛型。

2.什麼是泛型?

泛型,本質即“==類型參數化==”。一提到參數,最熟悉的就是定義方法時有形參,然後調用此方法時傳遞實參。那麼參數化類型怎麼了解呢?顧名思義,就是将類型由原來的具體的類型參數化,類似于方法中的變量參數,此時類型也定義成參數形式(可以稱之為類型形參),然後在使用/調用時傳入具體的類型(類型實參)。

public interface List<E> extends Collection<E> {

    int size();

    boolean isEmpty();

    boolean contains(Object o);

    Iterator<E> iterator();
           

我們可以看到,在List接口中采用泛型化定義之後,中的E表示類型形參,可以接收具體的類型實參,并且此接口定義中,凡是出現E的地方均表示相同的接受自外部的類型實參。

3.自定義泛型接口、泛型類和泛型方法

在泛型接口、泛型類和泛型方法的定義過程中,我們常見的如T、E、K、V等形式的參數常用于表示泛型形參,由于接收來自外部使用時候傳入的類型實參。那麼對于不同傳入的類型實參,生成的相應對象執行個體的類型是不是一樣的呢?

答:在使用泛型類時,雖然傳入了不同的泛型實參,但并沒有真正意義上生成不同的類型,傳入不同泛型實參的泛型類在記憶體上隻有一個,即還是原來的最基本的類型(本執行個體中為Box),當然,在邏輯上我們可以了解成多個不同的泛型類型。

究其原因,在于Java中的泛型這一概念提出的目的,導緻其隻是作用于代碼編譯階段,在編譯過程中,對于正确檢驗泛型結果後,會将泛型的相關資訊擦出,也就是說,成功編譯過後的class檔案中是不包含任何泛型資訊的。泛型資訊不會進入到運作時階段。

對此總結成一句話:泛型類型在邏輯上看以看成是多個不同的類型,實際上都是相同的基本類型。對象執行個體的類型是一樣的。

4.類型擦除和原始類型

類型擦除的由來 JVM中用确定類型替代泛型參數。

在JAVA的虛拟機中并不存在泛型,泛型隻是為了完善java體系,增加程式員程式設計的便捷性以及安全性而建立的一種機制,在JAVA虛拟機中對應泛型的都是确定的類型,在編寫泛型代碼後,java虛拟中會把這些泛型參數類型都擦除,用相應的确定類型來代替,代替的這一動作叫做類型擦除,而用于替代的類型稱為原始類型,在類型擦除過程中,一般使用第一個限定的類型來替換,若無限定則使用Object.

對泛型類的翻譯

是以在虛拟機翻譯泛型方法中,引入了==橋方法==

綜合以上,我們知道了泛型機制的實作實際上是編譯器幫我們分擔了一些麻煩的工作。一方面通過使用類型參數,可以告訴編譯器在編譯時進行類型檢查;另一方面,原本需要我們做的強制類型轉換的工作也由編譯器為我們代勞了

5.類型通配符

解決問題:是以,我們需要一個在邏輯上可以用來表示同時是Box和Box的父類的一個引用類型,由此,類型通配符應運而生。

類型通配符一般是使用 ? 代替具體的類型實參。注意了,此處是類型實參,而不是類型形參!且Box