Java泛型(Generic) 的引入加強了參數(shù)類型的安全性,減少了類型的轉換,它與C++中的模板(Temeplates) 比較類似,但是有一點不同的是:Java的泛型在編譯器有效,在運行期被刪除,也就是說所有的泛型參數(shù)類型在編譯后會被清除掉,我們來看一個例子,代碼如下:
程序很簡單,編寫了4個方法,arrayMethod方法接收String數(shù)組和Integer數(shù)組,這是一個典型的重載,listMethod接收元素類型為String和Integer的list變量?,F(xiàn)在的問題是,這段程序是否能編譯?如果不能?問題出在什么地方?
事實上,這段程序時無法編譯的,編譯時報錯信息如下:
這段錯誤的意思:簡單的的說就是方法簽名重復,其實就是說listMethod(List
List
List
List 、List 擦除后的類型為List
List
明白了這些規(guī)則,再看如下代碼:
經(jīng)過編譯后的擦除處理,上面的代碼和下面的程序時一致的:
Java編譯后字節(jié)碼中已經(jīng)沒有泛型的任何信息了,也就是說一個泛型類和一個普通類在經(jīng)過編譯后都指向了同一字節(jié)碼,比如Foo
避免JVM的大換血。C++泛型生命期延續(xù)到了運行期,而Java是在編譯期擦除掉的,我們想想,如果JVM也把泛型類型延續(xù)到運行期,那么JVM就需要進行大量的重構工作了。
版本兼容:在編譯期擦除可以更好的支持原生類型(Raw Type),在Java1.5或1.6...平臺上,即使聲明一個List這樣的原生類型也是可以正常編譯通過的,只是會產(chǎn)生警告信息而已。
明白了Java泛型是類型擦除的,我們就可以解釋類似如下的問題了:
泛型的class對象是相同的:每個類都有一個class屬性,泛型化不會改變class屬性的返回值,例如:
以上代碼返回true,原因很簡單,List
2.泛型數(shù)組初始化時不能聲明泛型,如下代碼編譯時通不過:
原因很簡單,可以聲明一個帶有泛型參數(shù)的數(shù)組,但不能初始化該數(shù)組,因為執(zhí)行了類型擦除操作,List