學(xué)習(xí)筆記

          Simple is beautiful.

          導(dǎo)航

          <2007年10月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          統(tǒng)計

          公告

          ...

          常用鏈接

          留言簿(1)

          隨筆分類(2)

          隨筆檔案(56)

          Weblog

          搜索

          最新評論

          評論排行榜

          JDK1.5中的泛型 - [Z]

          不小心看到有人批判jdk1.5,先說java要強制轉(zhuǎn)型不好的問題沒解決,容器不能放基類型不好,接著說泛型沒用。而恰恰Jdk1.5中解決了這些問題,所以感嘆之余,把這篇文章改一下,詳細(xì)的說說泛型。
          一,Java中的泛型:
              在Java中能使用到泛型的多是容器類,如各種list map set,因為Java是單根繼承,所以容器里邊可以放的內(nèi)容是任何Object,所以從意義上講原本的設(shè)計才是泛型。但用過Java的人是否感覺每次轉(zhuǎn)型很麻煩呢? 而且會有些錯誤,比如一個容器內(nèi)放入了異質(zhì)對象,強制轉(zhuǎn)型的時候會出現(xiàn)cast異常。而這中錯誤在編譯器是
          無從發(fā)現(xiàn)的。所以jdk1.5中提供了泛型,這個泛型其實是向c++靠攏了.好,我們先看幾個實例再細(xì)說原理。

          二,泛型的用法:(多個實例)

          1 實例A
          2 ArrayList < String >  strList  =   new  ArrayList < String > ();
          3 strList.add( " 1 " );
          4 strList.add( " 2 " );
          5 strList.add( " 3 " );
          6 // 關(guān)鍵點(1) 注意下邊這行,沒有強制轉(zhuǎn)型
          7 String str  =  strList.get( 1 );
          8 // 關(guān)鍵點(2)然後我們加入,這個時候你會發(fā)現(xiàn)編譯器報錯,錯誤在編譯器被發(fā)現(xiàn),錯誤當(dāng)然是發(fā)現(xiàn)的越早越好
          9 strList.add( new  Object());

          1 實例B
          2 ArrayList < Integer >  iList  =   new  ArrayList < Integer > ();
          3 // 關(guān)鍵點(3) 注意直接把整數(shù)放入了集合中,而沒有用Integer包裹
          4 iList.add( 1 );
          5 iList.add( 2 );
          6 iList.add( 3 );
          7 // 關(guān)鍵點(4)同樣直接取出就是int
          8 int  num  =  iList.get( 1 );

          1 實例C
          2 // 關(guān)鍵點(5)展示一下key-value的時候要怎么寫,同時key和value也可以是基本類型了。
          3 HashMap < Integer,Integer >  map  =   new  HashMap < Integer,Integer > ();
          4 map.put( 1 11 );
          5 map.put( 2 22 );
          6 map.put( 3 33 );
          7 int  inum  =  map.get( 1 );
          8

          三,看完了實例了,詳細(xì)來說說為什么吧
          首先jdk1.5中的泛型,第一個解決的問題,就是Java中很多不必要的強制轉(zhuǎn)型了,具體的實現(xiàn),我們以ArrayList
          為例,下邊是ArrayList中的片斷代碼:

           1ArrayList類的定義,這里加入了<E>
           2public class ArrayList<E> extends AbstractList<E>
           3        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
           4
           5//get方法,返回不再是Object 而是E
           6public E get(int index) {
           7    RangeCheck(index);
           8    return elementData[index];
           9}

          10//add方法,參數(shù)不再是Object 而是E
          11public boolean add(E o) {
          12    ensureCapacity(size + 1);  // Increments modCount!!
          13    elementData[size++= o;
          14    return true;
          15}

          16


          四,Boxing 和UnBoxing
          看到上邊的關(guān)鍵點(3)和(4)是否感覺驚奇呢,因為Java中煩人的除了強制轉(zhuǎn)型,另一個就是基礎(chǔ)類型了
          放入容器的時候要包裝,取出了還要轉(zhuǎn)回。Jdk1.5中解決了這個問題.如上邊的使用方法

          五,泛型的生命周期(使用注意事項)
          如果我們試著把ArrayList<String> list的內(nèi)容序列化,然後再讀取出來,在使用的過程中會發(fā)現(xiàn)出錯,
          為什么呢?用Stream讀取一下回來的數(shù)據(jù),你會發(fā)現(xiàn)<String>不見了,list變成了普通的ArrayList,而不是
          參數(shù)化型別的ArrayList了,為什么會這樣呢 ?見下邊的比較

          六,C++的泛型和Java的泛型
          在泛型的實現(xiàn)上,C++和Java有著很大的不同,
          Java是擦拭法實現(xiàn)的
          C++是膨脹法實現(xiàn)的
          因為Java原本實現(xiàn)就是泛型的,現(xiàn)在加入型別,其實是"窄化",所以采用擦拭法,在實現(xiàn)上,其實是封裝了原本的
          ArrayList,這樣的話,對于下邊這些情況,Java的實現(xiàn)類只有一個。

          1ArrayList<Integer>  .;   public class ArrayList
          2ArrayList<String>  ..;   --同上--
          3ArrayList<Double>  ..;   --同上--
          4而C++采用的是膨脹法,對于上邊的三種情況實際是每一種型別都對應(yīng)一個實現(xiàn),實現(xiàn)類有多個
          5list<int> li;                class list; //int 版本
          6list<string> ls;             class list; //string 版本
          7list<double> ld;             class list; //double 版本    

          這就造成了,在序列化后,Java不能分清楚原來的ArrayList是
          ArrayList<Integer>還是ArrayList

          七,題外話,在很多東西的實現(xiàn)上C++和Java有很多不同
          例如運算符的問題i=i++問題,詳細(xì)看這里
          例如在C++中能很好實現(xiàn)的double-checked locking單態(tài)模式,在Java中幾乎很難實現(xiàn) 詳細(xì)看這里
          還有就是上邊提到的泛型實現(xiàn)上。

          八,Jdk 1.5加入了不少新東西,有些能很大的提高開發(fā)質(zhì)量,例如Jdk1.4 ,Jdk.15中StringBuffer的不同
          因為從1。4轉(zhuǎn)入1。5不久,所以慢慢會發(fā)一些在1。5的使用過程中發(fā)現(xiàn)的東西。

          最后,我們還可以自己寫類似ArrayList這樣的泛型類,至于如何自定義泛型類,泛型方法請參見候捷先生的文章

          posted on 2007-10-23 01:57 Ecko 閱讀(285) 評論(0)  編輯  收藏


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 仲巴县| 蓬安县| 独山县| 同心县| 安龙县| 桦南县| 广水市| 来宾市| 内丘县| 固安县| 清水县| 揭东县| 咸丰县| 光山县| 宿迁市| 金平| 蒲江县| 安徽省| 惠东县| 凌源市| 丹巴县| 始兴县| 高邑县| 重庆市| 崇州市| 赤峰市| 澄迈县| 乐都县| 江源县| 仙桃市| 三台县| 定西市| 孝义市| 清原| 廊坊市| 新闻| 长白| 会同县| 泰和县| 珲春市| 太原市|