Posted on 2005-08-09 09:36
laogao 閱讀(5172)
評(píng)論(3) 編輯 收藏 所屬分類(lèi):
On Java
最近看到BlogJava上有人在討論為什么Java范型不支持?jǐn)?shù)組http://m.tkk7.com/myqiao/archive/2005/08/08/9580.html
我想這個(gè)問(wèn)題的答案是:因?yàn)檫@樣做會(huì)破壞類(lèi)型安全。核心的問(wèn)題在于Java范型和C#范型存在根本區(qū)別:Java的范型停留在編譯這一層,到了運(yùn)行時(shí),這些范型的信息其實(shí)是被抹掉的;而C#的范型做到了MSIL這一層。Java的做法不必修改JVM,減少了潛在的大幅改動(dòng)和隨之而來(lái)的風(fēng)險(xiǎn),也許同時(shí)也反映出Java Bytecode規(guī)范在設(shè)計(jì)之初的先天不足;C#則大刀闊斧,連CLR一起改以支持更徹底的范型,換句話(huà)說(shuō),在范型這一點(diǎn)上,感覺(jué)C#更C++一點(diǎn)。
在Java中,Object[]數(shù)組可以是任何數(shù)組的父類(lèi),或者說(shuō),任何一個(gè)數(shù)組都可以向上轉(zhuǎn)型成它在定義時(shí)指定元素類(lèi)型的父類(lèi)的數(shù)組,這個(gè)時(shí)候如果我們往里面放不同于原始數(shù)據(jù)類(lèi)型 但是滿(mǎn)足后來(lái)使用的父類(lèi)類(lèi)型的話(huà),編譯不會(huì)有問(wèn)題,但是在運(yùn)行時(shí)會(huì)檢查加入數(shù)組的對(duì)象的類(lèi)型,于是會(huì)拋ArrayStoreException:
String[] strArray = new String[20];
Object[] objArray = strArray;
objArray[0] = new Integer(1); // throws ArrayStoreException at runtime
因?yàn)?/SPAN>Java的范型會(huì)在編譯后將類(lèi)型信息抹掉,這樣如果Java允許我們使用類(lèi)似
Map<Integer, String>[] mapArray = new Map<Integer, String>[20];
這樣的語(yǔ)句的話(huà),我們?cè)陔S后的代碼中可以把它轉(zhuǎn)型為Object[]然后往里面放Map<Double, String>實(shí)例。這樣做不但編譯器不能發(fā)現(xiàn)類(lèi)型錯(cuò)誤,就連運(yùn)行時(shí)的數(shù)組存儲(chǔ)檢查對(duì)它也無(wú)能為力,它能看到的是我們往里面放Map的對(duì)象,我們定義的<Integer, String>在這個(gè)時(shí)候已經(jīng)被抹掉了,于是而對(duì)它而言,只要是Map,都是合法的。想想看,我們本來(lái)定義的是裝Map<Integer, String>的數(shù)組,結(jié)果我們卻可以往里面放任何Map,接下來(lái)如果有代碼試圖按原有的定義去取值,后果是什么不言自明。
所以,Java編譯器不允許我們new范型數(shù)組。