Java泛型小結

泛型作為Java進階必備知識,本文進行整理的學習筆記。

Java泛型小結

泛型作為Java1.5以後引入的一種編譯時泛化機制給Java語言提供了很大的靈活性,泛型的表現是參數化類型,通過參數化類型提高代碼的靈活性。

泛型的優點:

  • 編譯時檢查,保證類型安全

  • 消除類型檢查,提高代碼的可讀性

  • 提高了代碼的通用性

  • 提高了性能

泛型的基本使用

在Java中,泛型可以用於類、接口和方法的修飾,分別對應三種方式:泛型類、泛型接口和泛型方法

泛型類

在Java的Api中最典型的泛型類代表就是List、Map集合。

泛型類格式

class 類名稱 {}

注意:泛型的類型參數只能是類對象型,不能是簡單類型。

下面我們看一個簡單的泛型類:

Java泛型小結

泛型接口

泛型接口的形式跟泛型類基本相同,在Java中典型的泛型接口就是Iterator。

Java泛型小結

泛型接口格式

interface 接口名稱 {}

既然是接口,就少不了讓別的類來實現。所以這裡又會涉及到兩種形態:

  • 當實現泛型接口的類,未傳入泛型實參,即形式:class ConcreteGeneric

    implements Generic{}

Java泛型小結

  • 當實現泛型接口的類,傳入泛型實參,即形式:class ConcreteGeneric implements Generic

    {}

Java泛型小結

在實現類實現泛型接口時,如已將泛型類型傳入實參類型,則所有使用泛型的地方都要替換成傳入的實參類型

泛型方法

泛型方法是使用最多的一種泛型,使用的場景也比較多,比如泛型類中的泛型方法、普通類中的泛型方法、泛型方法與可變參數、靜態方法與泛型等。

泛型方法的格式

泛型方法需要使用< T >來指明泛型格式。比如:

public  void add(K name){ System.out.print(name);}

泛型方法與可變參數

Java泛型小結

靜態方法與泛型

Java泛型小結

泛型的邊界

Java中的泛型是在編譯期起到類型檢查作用,在運行期是不可見的。所以在使用泛型的時候,我們可以通過邊界限定來限制實參的類型。

泛型上邊界

泛型上邊界規定傳入的實參比繼續是指定類型的字類型。

格式:?extends 類型

表示類型的上界,表示參數化類型的可能是T 或是 T的子類

public class Generic

如上面所示,傳入的實參類型必須是BoundingType類型的子類。(BoundingType是一個類或者接口)。其中的BoundingType可以多於1個,用“&”連接即可。

上界類型通配符add方法受限,但可以獲取列表中的各種類型的數據,並賦值給父類型(extends Number)的引用。因此如果你想從一個數據類型裡獲取數據,使用 ? extends 通配符。限定通配符總是包括自己。

泛型下邊界

格式:?supper 類型

表示類型下界(Java Core中叫超類型限定),表示參數化類型是此類型的超類型(父類型),直至Object

下界類型通配符get方法受限,但可以往列表中添加各種數據類型的對象。因此如果你想把對象寫入一個數據結構裡,使用 ? super 通配符。限定通配符總是包括自己。

通配符

在java泛型中由於針對實參類型有很多不確定性,這裡就引出了通配符的概念。

  • ? 通配符類型

  • 表示類型的上界,表示參數化類型的可能是T 或是 T的子類

  • 表示類型下界(Java Core中叫超類型限定),表示參數化類型是此類型的超類型(父類型),直至Object

通配符與T的區別

  • T:作用於模板上,用於將數據類型進行參數化,不能用於實例化對象。

  • ?:在實例化對象的時候,不確定泛型參數的具體類型時,可以使用通配符進行對象定義。

案例一:定義一個泛型類

Java泛型小結

在定義泛型類的模版中,就必須使用T,不能用通配符來代替,通配符用於實例化對象中。

案例二:實例化泛型對象

Java泛型小結

我們不能夠確定list存儲的數據類型是Integer還是Long,因此我們使用List定義變量的類型。

泛型的原理

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

我們通過javap -c指令來查看一個.class文件

Java泛型小結

可以看到泛型方法中的實際泛型參數在虛擬機中都是Object類型。這也印證了Java中的泛型是偽泛型。

總結

在使用泛型的時候可以遵循一些基本的原則,從而避免一些常見的問題。

  1. 在代碼中避免泛型類和原始類型的混用。比如List

    和List不應該共同使用。這樣會產生一些編譯器警告和潛在的運行時異常。當需要利用JDK 5之前開發的遺留代碼,而不得不這麼做時,也儘可能的隔離相關的代碼。
  2. 在使用帶通配符的泛型類的時候,需要明確通配符所代表的一組類型的概念。由於具體的類型是未知的,很多操作是不允許的。

  3. 泛型類最好不要同數組一塊使用。你只能創建new List[10]這樣的數組,無法創建new List

    [10]這樣的。這限制了數組的使用能力,而且會帶來很多費解的問題。因此,當需要類似數組的功能時候,使用集合類即可。
  4. 不要忽視編譯器給出的警告信息。

1、Java中泛型 類型擦除

2、深入理解Java泛型

Java泛型小結


分享到:


相關文章: