Java泛型深入理解小總結(jié)

1摄狱、何為泛型
首先泛型的本質(zhì)便是類型參數(shù)化,通俗的說就是用一個變量來表示類型无午,這個類型可以是String,Integer等等不確定媒役,表明可接受的類型,原理類似如下代碼
int pattern; //聲明一個變量未賦值,pattern可以看作是泛型
pattern = 4;
pattern = 5;//4和5就可以看作是String和Integer

泛型的具體形式見泛型類宪迟、泛型方法

泛型類形式如下

*泛型方法舉例代碼如下
public <T> void show()
{
operation about T...
}
泛型參數(shù)類型聲明必須在返回類型之前
2酣衷、為何要引入泛型,即泛型與Object的優(yōu)勢
由于泛型可以接受多個參數(shù)次泽,而Object經(jīng)過強制類型轉(zhuǎn)換可以轉(zhuǎn)換為任何類型穿仪,既然二者都具有相同的作用,為何還要引進(jìn)泛型呢意荤?
解答:泛型可以把使用Object的錯誤提前到編譯后啊片,而不是運行后,提升安全性玖像。以下用帶泛型的ArrayList和不帶泛型的Arraylist舉例說明
代碼1:
ArrayList al = new ArrayList();al.add("hello");
al.add(4);//自動裝箱
String s1 = (String)al.get(0);
String s2 = (String)al.get(1);//在編譯時沒問題钠龙,但在運行時出現(xiàn)問題

首先聲明無泛型的ArrayList時,其默認(rèn)的原始類型是Object數(shù)組御铃,既然為Object類型碴里,就可以接受任意數(shù)據(jù)的賦值,因此編譯時沒有問題上真,但是在運行時,Integer強轉(zhuǎn)成String,肯定會出現(xiàn)ClassCastException.因此泛型的引入增強了安全性咬腋,把類轉(zhuǎn)換異常提前到了編譯時期。
3睡互、類型擦除和原始類型
  類型擦除的由來
在JAVA的虛擬機中并不存在泛型根竿,泛型只是為了完善java體系,增加程序員編程的便捷性以及安全性而創(chuàng)建的一種機制就珠,在JAVA虛擬機中對應(yīng)泛型的都是確定的類型寇壳,在編寫泛型代碼后,java虛擬中會把這些泛型參數(shù)類型都擦除妻怎,用相應(yīng)的確定類型來代替壳炎,代替的這一動作叫做類型擦除,而用于替代的類型稱為原始類型逼侦,在類型擦除過程中匿辩,一般使用第一個限定的類型來替換腰耙,若無限定則使用Object.

對泛型類的翻譯,泛型類(不帶泛型限定)代碼:

虛擬機進(jìn)行翻譯后的原始類型:
泛型類(帶泛型限定)代碼: 
虛擬機進(jìn)行翻譯后的原始類型:

泛型方法的翻譯


由于TestDemo繼承Test<String>,但是Test在類型擦除后還有一個public void Show(Object t),這和那個show(String t)出現(xiàn)重載铲球,但是本意卻是沒有show(Object t)的挺庞,
因此在虛擬機翻譯泛型方法中,引入了橋方法稼病,及在類型擦除后的show(Object t)中調(diào)用另一個方法选侨,代碼如下:
public void show(Object t){
show((String) t);
}
4、泛型限定
  泛型限定是通過然走?(通配符)來實現(xiàn)的侵俗,表示可以接受任意類型,那一定有人有疑問丰刊,那隘谣?和T(二者單獨使用時)有啥區(qū)別了,其實區(qū)別也不是很大啄巧,僅僅在對參數(shù)類型的使用上寻歧。例如:

? extends SomeClass 這種限定,說明的是只能接收SomeClass及其子類類型秩仆,所謂的“上限”
  ? super SomeClass 這種限定码泛,說明只能接收SomeClass及其父類類型,所謂的“下限”
一下舉例? extends SomeClass說明一下這類限定的一種應(yīng)用方式
由于泛型參數(shù)類型可以表示任意類型的類類型澄耍,若T要引用compareTo方法噪珊,如何保證在T類中定義了compareTo方法呢?利用如下代碼:
public <T extends Comparable> shwo(T a, T b){
int num = a.compareTo(b);
}
此處用于限定T類型繼承自Comparable,因為T類型可以調(diào)用compareTo方法齐莲。
  可以有多個類型限定痢站,例如:
<T extends Comparable & Serializable>

這種書寫方式為何把comparable寫在前邊?因為由于類型擦除的問題选酗,原始類型是由Comparable替換的阵难,因此寫在前邊的是類中存在此類型的泛型方法放在前邊,避免調(diào)用方法時類型的強制轉(zhuǎn)換芒填,提高效率呜叫。

關(guān)于泛型類型限定的“繼承”誤區(qū)
總有些人誤把類型的限定當(dāng)作繼承,比如:
//類型是這樣的
<Student extends Person>
//然后出現(xiàn)此類錯誤
ArrayList<Person> al = new ArrayList<Student>();
此處的<Person>, <Student>作為泛型的意思是ArrayList容器的接收類型殿衰,用一個簡單的例子來說明
ArrayList是一個大型養(yǎng)殖場朱庆,<Person>表明的是他能夠接收動物,而上邊的new語句生成的是一個只能夠接收豬的養(yǎng)殖場(ArrayList<Student>),即把一個大型養(yǎng)殖場建造成了一個養(yǎng)豬場闷祥,若是繼承的大型養(yǎng)殖場肯定是還能接受狗娱颊、羊....的,但是現(xiàn)在建造成了養(yǎng)豬場,那還能接受別的動物么维蒙?所以這肯定是錯誤的用法掰吕!簡而言之果覆,泛型new時兩邊的類型參數(shù)必須一致颅痊。
5、泛型的一些基本規(guī)則約束
  泛型的類型參數(shù)必須為類的引用局待,不能用基本類型(int, short, long, byte, float, double, char, boolean)
  泛型是類型的參數(shù)化斑响,在使用時可以用作不同類型(此處在說泛型類時會詳細(xì)說明)
  泛型的類型參數(shù)可以有多個,代碼舉例如下:
public <T, E> void show(){ coding operation..... }

泛型可以使用extends, super, ?(通配符)來對類型參數(shù)進(jìn)行限定
  由于類型擦除钳榨,運行時類型查詢只適用于原始類型舰罚,比如instanceof、getClass()薛耻、強制類型轉(zhuǎn)換营罢,a instanceof (Pair<Employe>),在類型擦除后便是 a instanceof Pair,因此以上運行的一些操作在虛擬機中操作都是對原始類型進(jìn)行操作,無論寫的多么虛幻饼齿,都逃不出類型擦除饲漾,因為在虛擬機種并不存在泛型。
  不能創(chuàng)建參數(shù)化類型的數(shù)組

例如寫如下代碼:
由于Object可以接收任何類型缕溉,在里邊存入 new Pari<Employe>時考传,沒有任何問題,但是當(dāng)取出的時候會出現(xiàn)ClassCastException,因此不能創(chuàng)建參數(shù)化類型數(shù)組证鸥。
  不能實例化類型變量僚楞,及不能出現(xiàn)以下的類似代碼
T t = new T();//或T.Class

因為在類型擦除后,便是Object t = new Object();與用意不符合枉层,即本意肯定不是要調(diào)用Object.
  不能再靜態(tài)域或方法中出現(xiàn)參數(shù)類型

例如如下錯誤代碼:
首先方法是一個返回類型為T的普通方法泉褐,而非泛型方法,這和在靜態(tài)方法中使用非靜態(tài)參數(shù)是一樣的鸟蜡,靜態(tài)方法是先于對象而存在內(nèi)存中的兴枯,因此在編譯的時候,T的類型無法確定矩欠,一定會出現(xiàn)“Cannot make a static reference to a non_static reference”這樣類似的錯誤财剖。
但是這樣的代碼就是正確的
class Test<T>{public static <T> T show() { action }}
因為此處的靜態(tài)方法是泛型方法,可以使用.
  不能拋出或捕獲泛型類的實例
    +不能拋出不能捕獲泛型類對象
    +泛型類不能擴展Throwable癌淮,注意是類不能繼承Throwable躺坟,類型參數(shù)的限定還是可以的。
    +catch子句不能使用類型變量乳蓄,如下代碼:

類型擦除后的沖突注意咪橙,例如:

此處的錯誤的原因不能存在同一個方法,在類型擦除后,Pair的方法為美侦,public boolean equals(Object value),這與從Object.class中繼承下來的equals(Object obj)沖突产舞。
  一個類不能成為兩個接口類型的子類,而這兩個接口是同一接口的不同參數(shù)化菠剩。
例如:
class Calendar implements coparable<Calendar>{}class GregorianCalendar extends Calendar implements Comparable<GregorianCalendar>{} //error

當(dāng)類型擦除后易猫,Calendar實現(xiàn)的是Comparable,而GregorianCalendar繼承了Calendar,又去實現(xiàn)Comparable,必然出錯具壮!
———————————————————————————————————————————————————————————————————————————————
先總結(jié)到此處准颓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市棺妓,隨后出現(xiàn)的幾起案子攘已,更是在濱河造成了極大的恐慌,老刑警劉巖怜跑,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件样勃,死亡現(xiàn)場離奇詭異,居然都是意外死亡性芬,警方通過查閱死者的電腦和手機峡眶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來批旺,“玉大人幌陕,你說我怎么就攤上這事∑螅” “怎么了搏熄?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長暇赤。 經(jīng)常有香客問我心例,道長,這世上最難降的妖魔是什么鞋囊? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任止后,我火速辦了婚禮,結(jié)果婚禮上溜腐,老公的妹妹穿的比我還像新娘译株。我一直安慰自己,他們只是感情好挺益,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布歉糜。 她就那樣靜靜地躺著,像睡著了一般望众。 火紅的嫁衣襯著肌膚如雪匪补。 梳的紋絲不亂的頭發(fā)上伞辛,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音夯缺,去河邊找鬼蚤氏。 笑死,一個胖子當(dāng)著我的面吹牛踊兜,可吹牛的內(nèi)容都是我干的竿滨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼润文,長吁一口氣:“原來是場噩夢啊……” “哼姐呐!你這毒婦竟也來了殿怜?” 一聲冷哼從身側(cè)響起典蝌,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎头谜,沒想到半個月后骏掀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡柱告,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年截驮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片际度。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡葵袭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乖菱,到底是詐尸還是另有隱情坡锡,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布窒所,位于F島的核電站鹉勒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吵取。R本人自食惡果不足惜禽额,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望皮官。 院中可真熱鬧脯倒,春花似錦、人聲如沸捺氢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讯沈。三九已至郁岩,卻和暖如春婿奔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背问慎。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工萍摊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人如叼。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓冰木,卻偏偏與公主長得像,于是被迫代替她去往敵國和親笼恰。 傳聞我的和親對象是個殘疾皇子踊沸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 泛型是Java 1.5引入的新特性。泛型的本質(zhì)是參數(shù)化類型社证,這種參數(shù)類型可以用在類逼龟、變量、接口和方法的創(chuàng)建中追葡,分別...
    何時不晚閱讀 3,037評論 0 2
  • 引言:泛型一直是困擾自己的一個難題腺律,但是泛型有時一個面試時老生常談的問題;今天作者就通過查閱相關(guān)資料簡單談?wù)勛约簩?..
    cp_insist閱讀 1,846評論 0 4
  • 在之前的文章中分析過了多態(tài)宜肉,可以知道多態(tài)本身是一種泛化機制匀钧,它通過基類或者接口來設(shè)計,使程序擁有一定的靈活性谬返,但是...
    _小二_閱讀 684評論 0 0
  • [TOC] 深入理解 Java 泛型 概述 泛型的本質(zhì)是參數(shù)化類型之斯,通常用于輸入?yún)?shù)、存儲類型不確定的場景遣铝。相比于...
    albon閱讀 5,314評論 0 7
  • Why ——引入泛型機制的原因 假如我們想要實現(xiàn)一個String數(shù)組佑刷,并且要求它可以動態(tài)改變大小,這時我們都會想到...
    absfree閱讀 5,110評論 1 6