Java 5.0引入泛型以后,提高了類型安全性,然而也給編程帶來了新的挑戰(zhàn)以及新的誤區(qū),類型轉(zhuǎn)換就是一個(gè)很好的例子。引入泛型以后,對(duì)象的類型似乎由兩個(gè)類型構(gòu)成:集合類型和參數(shù)類型,例如List<Integer> list = new LinkedList<Integer>(),似乎list的類型由List和Integer共同決定。如果真是這樣,那么我們?nèi)绻M麑?duì)list進(jìn)行類型轉(zhuǎn)換,我們?cè)撛趺崔k?是對(duì)List轉(zhuǎn)換,還是對(duì)Integer轉(zhuǎn)換?要解答上面的問題很簡單,編寫如下的代碼,運(yùn)行之就可看出端倪:





























如果你運(yùn)行上面的代碼,你會(huì)發(fā)現(xiàn)前一個(gè)函數(shù)根本無法通過編譯,而后一個(gè)函數(shù)不僅編譯成功,而且能得到正確結(jié)果。這似乎給出了一個(gè)結(jié)論:對(duì)象的類型由集合類型來決定,對(duì)對(duì)象進(jìn)行類型轉(zhuǎn)換時(shí)也是對(duì)集合類型進(jìn)行轉(zhuǎn)換。事實(shí)確實(shí)如此!那么為什么會(huì)如此呢?
我們可以回憶一下以前我們對(duì)參數(shù)類型的描述:參數(shù)類型不過是一個(gè)占位符而已,在編譯時(shí),它會(huì)被具體的類型代替,同時(shí)對(duì)添加到集合對(duì)象中的數(shù)據(jù)進(jìn)行參數(shù)檢查;如果添加到對(duì)象中的數(shù)據(jù)類型不是指定的具體類型或其子類型,則編譯出錯(cuò);而且,編譯以后,該占位符會(huì)被移除,運(yùn)行時(shí)你是無法得到任何集合類型中數(shù)據(jù)的類型信息的。簡而言之:
???????? List<String> strings = new LinkedList<String>( );
???????? List<Integer> ints = new LinkedList<Integer>( );
上面的代碼在運(yùn)行時(shí)和
???????? List strings = new LinkedList( );
???????? List ints = new LinkedList( );
毫無二致。了解了這一點(diǎn)以后,相信我們對(duì)于類型轉(zhuǎn)換也會(huì)有更深的理解了。
泛型給我們帶來了好處,使我們?cè)诰幾g時(shí)就能發(fā)現(xiàn)很多錯(cuò)誤;然而任何事物都是柄雙刃劍,泛型也不例外。泛型的缺點(diǎn)最明顯之處就在于類型轉(zhuǎn)換。如果你讀過前面的文章,肯定看到過不帶參數(shù)類型的集合對(duì)象轉(zhuǎn)換為帶參數(shù)類型的集合對(duì)象,其實(shí)不僅僅如此,這兩者之間可以任意轉(zhuǎn)換。這就意味著一點(diǎn),我們不僅可以對(duì)集合類型進(jìn)行轉(zhuǎn)換,也可以對(duì)參數(shù)類型進(jìn)行任意的轉(zhuǎn)換。這似乎與前面的描述不符,因?yàn)樯厦娴拇a中的List<Number> wrongList = list;根本無法編譯通過。確實(shí)如此,這行代碼確實(shí)無法編譯通過,不過我們中間做一步處理以后,上面的轉(zhuǎn)換就可以正常編譯了:
??????? List mediaList = list;
????????List<Number> wrongList = mediaList;
由此可見,泛型在給我們帶來好處的同時(shí),也帶來了無數(shù)陷阱,我們?cè)诰幊虝r(shí)需十分注意,而Java的泛型機(jī)制也需要不斷更新。
最后和以往一樣,以一個(gè)拙劣的程序結(jié)束本文:













































































































































































































































