在上一小節《泛型的深入理解和案例解析(1)—應用篇》我們知道了泛型的基本使用,並且也注意到泛型僅支援類型別,而不支援基本型別。
那麼問題出來了,類型別之間有繼承關係,泛型是不是支援呢,本節就將對這個問題進行深入分析。
問題1:比如乙個arraylist列表,要往裡邊放入數字,但是不確定integer long …,方便後續取出值計算。這個時候怎麼使用泛型?
實現見如下**:
class
listnum
number
>
extends
arraylist
使用如下效果:
listnum
listintegers =
newlistnum
();//編譯通過
listnum
liststrings =
newlistnum
();//編譯失敗 bound mismatch
問題2:有乙個函式,只接收包含number的arraylist,但不確定具體是哪個數字型別?
這時候就引入了萬用字元"?"。
我們在正規表示式中見過萬用字元,就是能夠匹配某一類字元的通用表示,"?"也是這個意思。
**實現如下:
private
static
void
set(arraylist<
?extends
number
> list)
set(
newarraylist
());
set(
newarraylist
());
// 報錯,引數不匹配
我們知道泛型除了有extends 還有乙個super,他們兩個什麼區別?
定義幾個型別如下:
class
smallcat
extends
catclass
catextends
animal
}class
dogextends
animal
}class
animal
}
考察extends和super是什麼性質。
extends繼承關係,繼承父類的方法,可以向上轉型為父類而不會出現錯誤。
使用場景:
(1) 泛型指代的引數型別,都擁有某個方法,或者都具有父類的某個屬性,可以用做多型使用的時候;如下**所示:
private
void
animalrun
(arraylist<
?extends
animal
> animals)
(2) 集合使用extends,對get賦值是開放的,對add是關閉的。因為允許儲存某個類的子類,這樣在取出的時候,賦值給父類引用,不會出現型別異常。但是add的時候,並不確定該集合是具體哪個型別,所以不允許。
**如下:
arraylist<
?extends
animal
> animals =
newarraylist
<
>()
; animals.
add(
newcat()
);//編譯報錯
animal animal = animals.
get(0)
;// 轉型正確
super 相當於指定某個類的所有可能父類,而父類和子類顯然沒有必然的關係。
使用場景:
(1)相較extends,super對get是關閉的,因為不確定集合內是具體哪個型別,取出賦值容易出現轉型錯誤;而add是開放的,因為只要保證是某個類的子類即可。
其實super實際中用的比較少,**如下:
arraylist<
?super cat> animals =
newarraylist
<
>()
; animals.
add(
newcat()
);animals.
add(
newsmallcat()
); animals.
add(
newanimal()
);//報錯
注意:super只能 「?」使用,t 是不支援的。 泛型的深入理解和案例解析(1) 應用篇
3.注意點 凡事一件事情的發生,必然有其合理性。泛型是jdk 1.5 加入的一種語言特性,它主要是為了解決在集合類元素預設object型別,新增元素沒有型別限制,導致執行時出現異常的問題。在我看來泛型主要解決兩個問題 編譯期的型別檢查。比如list指定型別,新增元素。動態化的引數型別繫結。比如泛型類...
深入理解泛型(一)
一 型別推斷 在我們寫泛型 的時候經常有大量的 符號,這樣有時候 一多,也難免會讓開發者在閱讀 過程中會覺得有點暈的,此時我們覺得暈的時候肯定就會這樣想 是不是能夠省掉一些 符號的呢?你有這種需求了,當然微軟這位好人肯定也會幫你解決問題的,這樣就有了我們這部分的內容 型別推斷 意味著編譯器會在呼叫乙...
C 泛型深入理解介紹
引言 在上乙個專題中介紹了c 2.0 中引入泛型的原因以及有了泛型後所帶來的好處,然而上一專題相當於是介紹了泛型的一些基本知識的,對於泛型的效能為什麼會比非泛型的效能高卻沒有給出理由,所以在這個專題就中將會介紹原因和一些關於泛型的其他知識。一 泛型型別和型別引數 泛型型別和其他int,string一...