首頁 > 科技

清華學霸首次分享!Java泛型全解寶典限時領取

2021-07-07 03:05:49

Hello,今天給各位童鞋們分享的是Java泛型,趕緊拿出小本子記下來吧

java泛型理解

泛型在java中經常使用,有很重要的作用,在做軟體構造的實驗,我對泛型的理解不是很深,但隨著瞭解和運用越來越多,理解也就加深了,這裡記錄一下學習的理解

什麼是泛型?

泛型,即「參數化類型」,是對java語言的類型系統的一種擴展,以支援創建可以按類型進行參數化的類,可以把類型參數看作是使用參數化類型時指定的類型的一個佔位符,就像方法的形式參數是運行時傳遞的值的佔位符一樣,泛型的本質是為了參數化類型,在不創建新的類型的情況下,通過泛型指定的不同類型來控制形參具體限制的類型,在泛型使用過程中,操作的資料類型被指定為一個參數,這種參數類型可以用在類、介面和方法中,分別被稱為泛型類、泛型介面、泛型方法。

對於常見的泛型模式,推薦的泛型類型變數有:

E:元素(element),多用於java集合框架

K:關鍵字(Key)

N:數字(Number)

T:類型(Type)

V:值(value)

T和T的區別:T是tpye的首字母縮寫;T表示「返回值」是一個泛型,傳入什麼類型,就返回什麼類型,而單獨的「T"表示限制傳入的參數類型

舉個例子說明泛型的作用

運行程式,崩潰

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

原因是ArrayList可以存放任意類型,例子中添加了一個String類型,添加了一個Integer類型,再使用時都以String的方式使用,因此程式崩潰了。為了解決類似這樣的問題(在編譯階段就可以解決),泛型應運而生。

我們將第一行聲明初始化list的程式碼更改一下,編譯器會在編譯階段就能夠幫我們發現類似這樣的問題。

泛型的特性

泛型只在編譯階段有效。看下面的程式碼:

輸出結果:D/泛型測試: 類型相同。

通過上面的例子可以證明,在編譯之後程式會採取去泛型化的措施。也就是說Java中的泛型,只在編譯階段有效。在編譯過程中,正確檢驗泛型結果後,會將泛型的相關資訊擦出,並且在物件進入和離開方法的邊界處新增類型檢查和類型轉換的方法。也就是說,泛型資訊不會進入到運行時階段。

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

泛型如何使用

泛型有三種使用方式,分別為:泛型類,泛型介面,泛型方法

1.泛型類

泛型類型用於類的定義中,最典型的是各種容器類,如:List,Set,Map

泛型的基本寫法:

舉個例子:

那如何使用呢

結果:

2.泛型介面

泛型介面與泛型類的定義及使用基本相同。泛型介面常被用在各種類的生產器中,可以看一個例子:

當實現泛型介面的類,未傳入泛型實參時:

當實現泛型介面的類,傳入泛型實參時:

3.泛型方法

泛型類,是在例項化類的時候指明泛型的具體類型;泛型方法,是在呼叫方法的時候指明泛型的具體類型 。

假設需要實現這樣一個方法:該方法負責將一個 Object 陣列的所有元素新增到一個 Collection 集合中。考慮採用如下程式碼來實現該方法:

上面定義的方法沒有任何問題,關鍵在於方法中的c 參數,它的資料類型是 Collection。正如前面介紹的,Collection 不是 Collection 的子類型—所以這個方法的功能很有限,它只能將 Object[] 陣列的元素複製到元素為 Object (Object 的子類不行)的Collection 集合中,擊下面程式碼會引起問題。

可見上面方法的參數類型不可以使用 Collection,使用通配符 Collection<?> 也不行,因為Java 不允許把物件放進一個未知類型的集合裡。為解決這個問題,可以使用泛型方法,在聲明方法時定義一個或多個類型形參。泛型用法格式如下:

該泛型方法的方法簽名比普通方法的方法簽名多了類型形參聲明,類型形參聲明以尖括號括起來,多個類型形參直接以逗號(,)隔開,所有的類型形參聲明放在方法修飾符和返回值類型之間。採用支援泛型的方法,就可以將上面的 fromArrayToCollection 方法改寫為如下形式

可以看到Object被替換成了T,而且在修飾符和返回值中間加了

下面程式碼示範了完整用法

上面程式呼叫了一個泛型方法,該泛型方法中定義了一個 T 類型形參,這個 T 類型形參就可以在該方法內當成普通類型使用。與介面、類聲明中定義的類型參數不同的是,方法聲明中定義的形參只能在該方法內使用,而介面、類聲明中定義的類型形參則可以在整個介面、類中使用。

與類,介面中泛型參數不同的是,方法中的泛型參數無須顯式傳入實際類型參數,如上面程式所示,當程式呼叫 fromArrayToCollection() 方法時,無須在呼叫該方法前傳入String、Object 等類型,但系統依然可以知道類型參數的資料類型,因為編譯器根據實參推斷類型實參的值,它通常推斷出最直接的類型參數。

好啦,今天的文章就到這裡了,希望能夠幫助到螢幕前迷茫的你們


IT145.com E-mail:sddin#qq.com