Read Sean

          Read me, read Sean.
          posts - 508, comments - 655, trackbacks - 9, articles - 4

          為什么Java不支持創(chuàng)建范型數(shù)組?

          Posted on 2005-08-09 09:36 laogao 閱讀(5172) 評論(3)  編輯  收藏 所屬分類: On Java

           

          最近看到BlogJava上有人在討論為什么Java范型不支持?jǐn)?shù)組http://www.aygfsteel.com/myqiao/archive/2005/08/08/9580.html

           

          我想這個問題的答案是:因?yàn)檫@樣做會破壞類型安全。核心的問題在于Java范型和C#范型存在根本區(qū)別:Java的范型停留在編譯這一層,到了運(yùn)行時(shí),這些范型的信息其實(shí)是被抹掉的;而C#的范型做到了MSIL這一層。Java的做法不必修改JVM,減少了潛在的大幅改動和隨之而來的風(fēng)險(xiǎn),也許同時(shí)也反映出Java Bytecode規(guī)范在設(shè)計(jì)之初的先天不足;C#則大刀闊斧,連CLR一起改以支持更徹底的范型,換句話說,在范型這一點(diǎn)上,感覺C#C++一點(diǎn)。

           

          Java中,Object[]數(shù)組可以是任何數(shù)組的父類,或者說,任何一個數(shù)組都可以向上轉(zhuǎn)型成它在定義時(shí)指定元素類型的父類的數(shù)組,這個時(shí)候如果我們往里面放不同于原始數(shù)據(jù)類型 但是滿足后來使用的父類類型的話,編譯不會有問題,但是在運(yùn)行時(shí)會檢查加入數(shù)組的對象的類型,于是會拋ArrayStoreException

           

          String[] strArray = new String[20];

          Object[] objArray = strArray;

          objArray[0] = new Integer(1); // throws ArrayStoreException at runtime

           

          因?yàn)?/SPAN>Java的范型會在編譯后將類型信息抹掉,這樣如果Java允許我們使用類似

           

          Map<Integer, String>[] mapArray = new Map<Integer, String>[20];

           

          這樣的語句的話,我們在隨后的代碼中可以把它轉(zhuǎn)型為Object[]然后往里面放Map<Double, String>實(shí)例。這樣做不但編譯器不能發(fā)現(xiàn)類型錯誤,就連運(yùn)行時(shí)的數(shù)組存儲檢查對它也無能為力,它能看到的是我們往里面放Map的對象,我們定義的<Integer, String>在這個時(shí)候已經(jīng)被抹掉了,于是而對它而言,只要是Map,都是合法的。想想看,我們本來定義的是裝Map<Integer, String>的數(shù)組,結(jié)果我們卻可以往里面放任何Map,接下來如果有代碼試圖按原有的定義去取值,后果是什么不言自明。

           

          所以,Java編譯器不允許我們new范型數(shù)組。

           

           

          Feedback

          # re: 為什么Java不支持創(chuàng)建范型數(shù)組?  回復(fù)  更多評論   

          2008-05-31 00:37 by dieyingao
          突然看到,踩一下. 貌似和java對 泛型繼承上改成 <? extends T>的原因類似.

          # re: 為什么Java不支持創(chuàng)建范型數(shù)組?  回復(fù)  更多評論   

          2009-10-16 09:25 by 深夜兩點(diǎn)
          我分析了一下為啥不支持泛型的數(shù)組。其實(shí)支持也不會引發(fā)什么大的問題,只不過是個面子問題。

          http://www.aygfsteel.com/deepnighttwo/articles/298426.html

          # re: 為什么Java不支持創(chuàng)建范型數(shù)組?  回復(fù)  更多評論   

          2009-10-16 11:14 by 大胃
          其實(shí)問題的關(guān)鍵是Java數(shù)組的實(shí)現(xiàn),當(dāng)時(shí)條件艱苦,類型系統(tǒng)不夠發(fā)達(dá),它需要一種"簡單粗暴"的方式支持協(xié)變,比方說Object[]可以是所有其他元素類型的數(shù)組比如Integer[]的父類,這樣在方法簽名或變量定義中可以用Object[]"通殺"所有數(shù)組。

          所以Java數(shù)組就有了編譯期不檢查(沒法檢查),而在運(yùn)行期保有類型信息并進(jìn)行檢查的行為(為類型安全),盡管這樣的實(shí)現(xiàn)看上去既不安全,也不高效。

          有了泛型,不論是否有type-erasure,我們可以在很多場合避開對類似Object[]寫法的依賴,更好也更清楚的表達(dá)我們的真實(shí)意圖,從這個角度講,Java的泛型是有它積極的一面的,只是別跟數(shù)組這個老家伙較勁就好了。
          主站蜘蛛池模板: 禹州市| 威远县| 衡阳县| 巴塘县| 鸡东县| 铜鼓县| 德昌县| 安丘市| 浠水县| 葫芦岛市| 缙云县| 通化市| 琼中| 梓潼县| 曲靖市| 遂川县| 永嘉县| 化隆| 荔浦县| 汽车| 邹平县| 屯昌县| 正蓝旗| 孝昌县| 贵阳市| 察哈| 凤城市| 祁门县| 泰和县| 利川市| 崇左市| 灌阳县| 都匀市| 江油市| 昭通市| 高青县| 东乌珠穆沁旗| 衡东县| 长汀县| 舒城县| 丰县|