Java 5.0引入泛型以后,提高了類型安全性,然而也給編程帶來了新的挑戰以及新的誤區,類型轉換就是一個很好的例子。引入泛型以后,對象的類型似乎由兩個類型構成:集合類型和參數類型,例如List<Integer> list = new LinkedList<Integer>(),似乎list的類型由List和Integer共同決定。如果真是這樣,那么我們如果希望對list進行類型轉換,我們該怎么辦?是對List轉換,還是對Integer轉換?要解答上面的問題很簡單,編寫如下的代碼,運行之就可看出端倪:





























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













































































































































































































































