Picses' sky

          Picses' sky
          posts - 43, comments - 29, trackbacks - 0, articles - 24
          ?

          “泛型Java”,一個(gè)美麗的hype

          今天,Sun發(fā)布了J2SE 1.5新特性的一個(gè)原型實(shí)現(xiàn)版本。這個(gè)運(yùn)行在J2SE 1.4上的插件提供了J2SE 1.5主要的幾項(xiàng)新特性,例如類型安全的枚舉、自動(dòng)裝箱/拆箱、增強(qiáng)的for循環(huán)等,當(dāng)然還有最受關(guān)注的JSR-14,泛型。

          在試用了這些新特性之后,我終于對(duì)Java的泛型徹底失望了。首先,我們來看看泛型Java的經(jīng)典用法:

          import java.util.*;

          ?

          public class UseGeneric

          {

          ??? public static void main(String[] args)

          ??? {

          ??? ??? Vector<Integer> vi = new Vector<Integer>();

          ??? ??? vi.add(new Integer(24));

          ??? ??? vi.add(35);

          ?

          ??? ??? for(Integer i : vi)

          ?????? {

          ?????? ??? System.out.println(i);

          ?????? }

          ??? }

          }

          上面的代碼展示了泛型容器、自動(dòng)裝箱和增強(qiáng)for循環(huán)三項(xiàng)新特性。的確,從簡(jiǎn)化代碼的角度來說,這些新特性有一定的幫助——當(dāng)然,自動(dòng)裝箱其實(shí)不應(yīng)該算一項(xiàng)很有意義的特性,只是因?yàn)?/span>Java固有的兩套類型體制將intchar等原生類型與對(duì)象區(qū)分對(duì)待,所以在引入泛型容器時(shí)不得不采用自動(dòng)裝箱作為補(bǔ)救。

          將上面的代碼編譯后的class進(jìn)行反編譯,得到下列代碼:

          import java.io.PrintStream;

          import java.util.Vector;

          ?

          public class UseGeneric

          {

          ?

          ??? public UseGeneric()

          ??? {

          ??? }

          ?

          ??? public static void main(String args[])

          ??? {

          ??? ????Vector vector = new Vector();

          ??????? vector.add(new Integer(24));

          ??????? vector.add(Integer.valueOf(35));

          ??????? Integer integer;

          ??????? for(SimpleIterator simpleiterator = vector.iterator(); simpleiterator.hasNext(); System.out.println(integer))

          ??????????? integer = (Integer)simpleiterator.next();

          ?

          ??? }

          }

          可以看到,所有的新特性都是在現(xiàn)有虛擬機(jī)的基礎(chǔ)上實(shí)現(xiàn)的,沒有任何新鮮感可言。的確如Joshua Bloch所說的,只不過是把以前由程序員寫的一些代碼轉(zhuǎn)成由編譯器來寫。

          隨后我試圖實(shí)現(xiàn)一些略微高級(jí)的泛型技術(shù),例如type traits。我寫了下列代碼:

          // General Traits

          class NumTraits<T>

          {

          ??? public void doSomething()

          ??? {

          ??? ??? System.out.println("General Traits");

          ??? }

          }

          ?

          // Specialized Traits

          class NumTraits<Integer)

          {

          ??? public void doSomething()

          ??? {

          ??? ??? System.out.println("Traits for Integer");

          ??? }

          }

          可惜,這段代碼不能通過編譯,編譯器提示“duplicate class”。顯然,編譯器并沒有把類型參數(shù)作為類名稱的一部分,因此traits是不可能實(shí)現(xiàn)的了。當(dāng)然,在成員方法中可以編寫類似于模板特化(specialization)甚至偏特化(partial-specialization)的代碼,但是下面的代碼將證明這種東西毫無意義。

          public class Happy<T>

          {

          ??? private T subject = new T();

          ?

          ??? public <T> void happy()

          ??? {

          ??? ??? subject.beHappy();

          ??? }

          ?

          ??? public static void main(String[] args)

          ??? {

          ??? ??? Happy<Dog> o1 = new Happy<Dog>();

          ??? ??? o1.happy();

          ?

          ??? ??? Happy<Cat> o2 = new Happy<Cat>();

          ??? ??? o2.happy();

          ??? }

          }

          這里的編譯錯(cuò)誤有兩種。首先,“private T subject = new T();”這個(gè)語句不能編譯,也許是我還沒有找到實(shí)例化類型參數(shù)的正確方法吧。更重要的是,編譯器提示“在java.lang.Object中找不到happy()方法”。由于Java采用“擦拭法”實(shí)現(xiàn)泛型,所有類型參數(shù)(除非顯式聲明超類或接口)都將被擦拭為Object,因此方法調(diào)用的契約仍然完全依賴對(duì)象系統(tǒng)來保證。換句話說,類似于模板特化之類的技巧不但在效率上毫無幫助,而且根本無法像C++那樣依賴編譯器進(jìn)行比較高級(jí)的檢查甚至編譯期計(jì)算。TypelistSelect模板?還是不要想了吧。

          喏,這就是所謂的“泛型Java”。沒有編譯期動(dòng)態(tài)綁定,沒有type-traits,沒有(真正的)模板特化,一切的問題依然扔給RTTI來完成。我更愿意把它叫做“Java with some type-safe containers”,而不是“Generic Java”。

          泛型Java,一個(gè)美麗的hype——如果你對(duì)它有太多期望的話。


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 陆丰市| 平定县| 儋州市| 阳高县| 香港| 汪清县| 英吉沙县| 兰西县| 申扎县| 固镇县| 神木县| 沭阳县| 扶绥县| 崇明县| 柘城县| 和田县| 衡水市| 长葛市| 吉首市| 瓮安县| 扎兰屯市| 静海县| 阳城县| 英超| 额尔古纳市| 广东省| 射阳县| 固镇县| 博客| 张掖市| 岑溪市| 江永县| 东乌珠穆沁旗| 乌拉特前旗| 绥化市| 环江| 龙南县| 台中市| 阳新县| 宣汉县| 沁水县|