1. 程式人生 > 實用技巧 >乾飯人!多執行緒鎖分類你不看看嗎?肆

乾飯人!多執行緒鎖分類你不看看嗎?肆

1、為什麼要使用泛型?

(1)適用於多種資料型別執行相同的程式碼,利於封裝(如,封裝Base類、統一的適用於recycleview的adapter等)

(2)泛型中的型別在使用的時候,直接指定即可,不需要進行強制轉換。資料轉換是很容易帶來資料異常的,尤其是當服務端傳過來的資料與我們接收的資料型別不同的時候。

2、泛型類、泛型介面、泛型方法?

泛型方法

引入一個型別變數T(其他大寫字母都可以,不過常用的就是TEKV等等),並且用<>括起來,並放在類名的後面。泛型類是允許有多個型別變數的。例如:

一個型別變數

兩個型別變數

泛型介面

泛型介面與泛型類的定義基本相同

而實現泛型介面的類有兩種實現方法:

(1)未傳入泛型引數時,那麼該類也屬於泛型類

那麼在new出該例項物件時,需要指定具體型別

(2)在實現泛型介面時,傳入泛型引數。

那麼在new出該類的例項時,與普通的類就沒區別了。

泛型方法

public代表修飾符,<T>表示泛型方法,緊跟後面的T表示返回值。

泛型方法是在呼叫方法的時候指明泛型的具體引數型別,泛型方法可以在任何場景中使用,包括普通類和泛型類。但是在泛型類中定義普通方法和泛型方法是有區別的:

普通方法:

泛型方法:

關鍵點:<T>

3、限定型別變數

有時候我們需要對變數型別進行約束。比如我們定義一個泛型方法:

如何才能夠保證傳進來的a、b兩個引數一定有compareTo方法呢?那麼我們就要對T進行約束,保證傳進來的T引數的型別實現了Comparable類

T extends Comparable表示,傳進來的例項物件必須實現了Comparable類,否則將發生編譯錯誤

extends左右都允許有多個,如T,Vextends Comparable & Serializable

注意限定型別的時候,只允許有一個類,允許多個介面,如果所限定的型別包含類和介面,那麼類要放在最前面,也就是緊跟extends之後的第一個要放類。

型別限定既可以放在泛型方法上,也可以用在泛型類上

T super XXX跟 extends用法一樣,只不過super表示傳入的型別T只能是XXX或XXX的父類,最高為object類

4、泛型中的約束和侷限性

現在我們有泛型類

(1)不能用基本型別例項化

(2)執行時,型別查詢只適用於原始型別

因為型別擦除,java虛擬機器中的物件並沒有泛型類這一說,instanceofgetClass()只能查詢到原始型別, 具體的泛型型別時無從得知的。

(3)泛型類的靜態上下文中型別變數失效

不能在靜態域或靜態方法中使用泛型。因為泛型是需要我們在建立物件的時候才知道是什麼型別,而物件建立過程中,程式碼的執行先後順序是最先執行static部分,然後才是建構函式等。

因此,在物件初始化之前static部分的程式碼已經執行,而此時的static塊並不知道到底是什麼型別,因為這個時候我們的物件還沒初始化。

(4)不能建立引數化型別的陣列

例如Restrict<Double> array = new Restrict<Double>[10]是錯誤的,

我們只能宣告Restrict<Double>[] array;

(5)不能例項化型別變數

(6)不能補貨泛型類的例項

但可以這樣

5、泛型型別的繼承規則

現在我們有一個類和子類

有一個泛型類

Pair<Employee>和Pair<Worker>之間沒有任何關係

但是泛型類之間可以繼承和擴充套件其他泛型類,例如:List和ArrayList

泛型類和泛型介面