天天看點

[Java] 泛型Generic

泛型Generic

目錄

一、什麼是泛型?

二、為什麼要引入泛型?

三、泛型的使用

3.1 泛型方法

泛型的第一個好處,保證運作時安全。

第二個好處,節約資源。

3.2 泛型類3.2.1 自定義泛型類

3.3 泛型接口

3.4 泛型方法

3.5 通配符

四、 泛型注意事項

​ 泛型是JDK5中引入的,泛型是一種參數化類型。

​ 泛型是限定參數類型的參數。它是參數,用于限定傳遞的對象的類型。

​ 先來看一個例子。

​ 我們首先定義兩個相似的Dog、Cat類。

​ 接着在測試類中進行如下操作。

​ 上述例子我們在動态數組中加入了兩個Dog對象。在使用for-each循環周遊這個數組時,為了通路到Dog類中的私有屬性,我們需要調用Dog類中的方法。對 obj 向下轉型成Dog對象。

​ 到這裡看是沒有任何問題的,因為在向動态數組中添加元素時,我們清楚的知道添加的元素的類型,這似乎是沒有什麼問題的。但是,首先由于資料量小,我們可以清楚的知道元素的類型,那麼資料量大的時候呢?還能保證每個被添加的元素的類型和我們想象中一緻嗎?第二,list這個對象變量是我們自己建立的,我們清楚的知道我要用它來存儲什麼類型的元素,對于其他人而言,他會認為這是一個任何類型元素都可以儲存的數組,這會造成什麼情況呢?

​ 抛出ClassCastException異常。

​ 是以引入泛型就很有必要

①保證程式運作的安全。上面就是一個例子,至于如何保證安全在後面會說到。

②節約資源。這點也會在後面說到

​ 由前面所言,我們知道:泛型是一種類型參數,用于限定在方法、類間傳遞參數的類型。

​ 我們對上面的代碼進行些許的改變。

​ 改變在于在建立 對象變量list的時候多出了一個<>,Java中把這個叫做菱形運算符,在其中輸入我們的類型參數。

​ 以該句為例,List list,<>内的Dog作為參數存在,隻起限制作用,它限制了傳入list集合内的元素類型隻能為Dog類。

​ 在對list限制後,向list内添加Cat類元素,編譯器會自己報錯。

​ 在申請對象變量時對其傳入參數作出限制,在傳入元素類型不一緻時,編譯器會自動報錯,避免了元素類型強制轉換時錯誤。

![泛型好處二 節約資源](D:\桌面\MarkDown\泛型\泛型好處二 節約資源.png)

​ 再次對上面代碼進行調整,for-each中的Object obj替換成了Dog dog,在未使用泛型時,編譯器為了保證減少錯誤,Object obj是不允許更改的。

​ 未經過泛型限定的集合輸出時元素的類型轉換(以Dog為例):Dog -> Object -> Dog

​ 經過泛型限定的集合輸出時元素的類型轉換 : Dog -> Dog-> Dog

在類名後采用菱形運算符<>,并且給定參數類型的類稱為自定義泛型類

參數類型通常用單個大寫字母表示,理論上任何大寫字母都可以,為了清晰的表示參數類型所指,通常使用E、K、V、T等

普通成員、構造函數、私有屬性、數組均可以為泛型類型

泛型數組不能初始化

靜态方法無法通路類上定義的泛型;如果靜态方法操作的引用資料類型不确定的時候,必須要将泛型定義在方法上。因為靜态屬性、方法和類一起初始化,在類初始化時無法确定泛型屬性或泛型方法的具體類型。

接上條,如果靜态方法要使用泛型的話,必須将靜态方法也定義成泛型方法 。

泛型類的類型變量在類執行個體化時确定

​ 自定義一個泛型接口Gt01。

接口中無法定義泛型屬性,因為接口屬性預設為public static final

類型變量在實作接口時确定,預設為Object

​ 1.泛型方法既可以定義在泛型類中,也可以定義在普通類中

​ 2.泛型方法也用菱形運算發标注,但與泛型類與泛型接口不同的是,标注的位置不同。

​ 3.泛型方法的類型變量隻用于該方法中

​ 4.使用了泛型的方法和泛型方法的差別

支援任意泛型類型

支援A類及其A類的子類,限定泛型上限

支援A類及其父類,不限于直接父親,限定了泛型下限

泛型在限定時隻能時引用類型,不能時基本類型

在給出泛型的具體類型後,可以傳入該類型或其子類類型

泛型定義時,後面的菱形運算符内可以省略

[泛型類、泛型接口、泛型方法]在不給定類型參數的情況下,預設為類型參數為Object