<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    博客已轉到HuJinPu 's blog

    http://blog.csdn.net/hujinpu

    首頁 新隨筆 聯系 聚合 管理
      24 Posts :: 0 Stories :: 25 Comments :: 0 Trackbacks

    大家先看看下面這段小程序

    import ?java.util.ArrayList;
    import ?java.util.List;

    // 申明一個泛型類
    public ? class ?GenericClass? {
    ????
    ????
    public ? static ? void ?main(String?[]?args)? {
    ????????List
    < Integer > ?list? = ? new ?ArrayList < Integer > ();
    ????????list.add(
    1 );
    ????????list.add(
    2 );
    ????????
    new ?Product().prt(list);
    ????}

    }


    // 制造一個類用于說明問題
    class ?Product ? {
    ????
    public ? void ?prt(List < String > ?lt)? {
    ????????System.out.println(lt);
    ????}

    }


    ?

    編譯器報錯,說無法將Product中的prt(java.util.List<java.lang.String>)應用于(java.util.List<java.lang.Integer>)。前面定義了List<Integer> list = new ArrayList<Integer>();后面卻調用 public void prt(List<String> lt)用list做參數,肯定是錯誤的用法。編譯器報錯的行為是很正確的,他幫助你避免了潛在錯誤的發生。這里要注意泛型的作用:List<Integer>和List<String>雖然看著都是List,但編譯器把他們當作不同的class,不能相互替代。這是泛型的基本原則。你可以把他們看成一個是Class1, 一個是Class2, 當然不能給一個需要類型為Class1的參數的方法傳一個類型為Class2的參數的方法啦。

    再來看上面程序稍微改動一處的情況

    import ?java.util.ArrayList;
    import ?java.util.List;

    // 申明一個泛型類
    public ? class ?GenericClass? {
    ????
    ????
    public ? static ? void ?main(String?[]?args)? {
    ????????List
    < Integer > ?list? = ? new ?ArrayList < Integer > ();
    ????????list.add(
    1 );
    ????????list.add(
    2 );
    ????????
    new ?Product().prt(list);
    ????}

    }


    // 制造一個類用于說明問題
    class ?Product < T > ? {
    ????
    public ? void ?prt(List < String > ?lt)? {
    ????????System.out.println(lt);
    ????}

    }


    編譯器說使用了未經檢查或不安全的操作,但能編譯通過并運行顯示 [1, 2]。

    這又是為什么呢?就是紅色的那一個<T>就變化這么大嗎?似乎不是和剛才效果應該一樣拉,怎么這回又可以了?

    原因是這樣的:第次程序里面,只是把class Product改成了class Product<T>,盡管類型T在Product的代碼里壓根從沒用到,但是這個定義把一個普通類(class)變成了原始類型(raw class)。generic class Product<T>在JVM運行時是不存在的,Product這個原始類型不是類型安全的。因為在new Product.prt(list)里面,使用的是原始類型的Product,所以里面的list也會被擦拭成原始類型的,所以類型就符合了,不會有編譯錯誤而可以運行。

    雖然這個時候程序盡管可以運行,但其使用泛型的方法,無疑是錯誤的。 在這里我只是想和大家分析一些泛型的細節問題。要大家通過這個細節明白泛型的細節之處(檫試,原始類型)。具體的內容我就不在說了,很多書都有。推薦java參考大全5edition page264 和 core Java I 7edition Chapter 13. Generic Programming??

    posted on 2006-08-28 16:19 livahu 閱讀(1637) 評論(5)  編輯  收藏 所屬分類: Java

    Feedback

    # re: 關于jdk1.5泛型的思考 2006-08-28 17:17 海藍
    @livahu
    你在原因部分說的內容我看不懂啊,感覺你說的原因和結果之間似乎沒什么必然的聯系,可以再整理一下嗎?  回復  更多評論
      

    # re: 關于jdk1.5泛型的思考 2006-08-28 18:29 路人甲
    這個問題我想的確是作者沒有說清楚。不過只要親自用編譯器試一下應該就可以很容易理解了。這里斗膽幫作者稍微深入地解釋一下,如果說錯了還請不吝賜教,但愿不會誤人子弟。

    首先,第一段程序里面,前面定義了List<Integer> list = new ArrayList<Integer>();
    后面卻調用void prt(List<String> l)用list做參數,肯定是錯誤的用法。編譯器報錯的行為是很正確的,他幫助你避免了潛在錯誤的發生。

    這里要注意泛型的作用。List<Integer>和List<String>雖然看著都是List,但編譯器把他們當作不同的class,不能相互替代。這是泛型的基本原則。你可以把他們看成一個是Class1, 一個是Class2, 當然不能給一個需要類型為Class1的參數的方法傳一個類型為Class2的參數的方法啦。

    而第二段程序里面,只是把class Product改成了class Product <T>,盡管類型T在Product的代碼里壓根從沒用到,只是這個定義把一個普通類(class)變成了原始類型(raw class)。其實可以自己試一下,一旦把Fangxin.main()里面的new Product().prt(list) 改成了new Product<Integer>().prt(list), (這里面的Integer可以換成任何一個合法的類),那么warning沒有了,原來的error又回來了。

    也就是說,一旦把Product定義成了原始類型,那么在使用這個class的時候也就應該使用Product<T>的形式,否則的話,編譯器會認為你的行為不正常或是很危險,所以給你一個warning(也許你只是忘了寫呢)。正像作者原文里寫道的:

    generic class Product<T>在JVM運行時是不存在的,Product叫原始類型,原始類型不是類型安全的.這個在編譯時是檢測不出的,運行時才報錯.
    (這里其實不會報錯,只是因為可能會報錯,所以編譯器給你一個warning)。

    而當一個generic class使用原始類型時,其方法里的參數也就相應的使用了原始形態,如此列的java.util.List而不是java.util.List<String>
    固new Product().prt(lt)時可以運行.

    (這句是說,因為在new Product.prt(list)里面,你使用的是原始類型的Product,所以里面的list也是原始類型的,所以類型就符合了,不會有編譯錯誤而可以運行)。

    但是這個時候盡管可以運行,但程序的邏輯,至少其使用泛型的方法,無疑是錯誤的。

    個人認為這個程序應該改成這樣才是正確地使用泛型編程的方式:

    import java.util.ArrayList;
    import java.util.List;

    public class Fangxin {

    public static void main(String [] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    new Product<Integer>().prt(list);
    }

    }

    class Product<T> {
    public void prt(List<T> l) {
    System.out.println(l);
    }
    }

    最后加一句,編譯器給出error和warning不是故意跟你作對,給你添麻煩,而是為你寫出正確的程序提出最好的幫助。所以應該盡量讓程序沒有任何編譯錯誤(這個自然)和警告才是正途。  回復  更多評論
      

    # re: 關于jdk1.5泛型的思考 2006-08-28 20:52 livahu
    很感謝路人甲的指正,我確實沒有表達清楚我的想法,我想通過路人甲的指正,大家應該明白了泛型的細節之處,這里的帶有明顯錯誤和警告的程序不是要大家去模仿,而是要大家通過這個細節明白泛型的細節之處(檫試,原始類型).具體的內容我就不在說了,很多書都有,推薦java參考大全5edition page264 和 core Java I 7edition Chapter 13. Generic Programming  回復  更多評論
      

    # re: 關于jdk1.5泛型的思考 2006-08-29 09:00 Dedian
    good article, just for supplement:

    http://m.tkk7.com/dedian/archive/2006/06/23/54615.html  回復  更多評論
      

    # re: 關于jdk1.5泛型的思考 2006-09-01 10:16 Spike Wang
    這樣的用法1.5以后才有,最好不要亂用泛型。

    我建議如果是新項目使用無所謂。

    如果是和以前系統協作那么最好避免。

    免得給自己找麻煩。

    在泛型還么大量使用的時候,盡量避免使用。

      回復  更多評論
      

    主站蜘蛛池模板: 亚洲成a人片在线观看中文app| 国产成人亚洲综合无码精品 | 亚洲精品自在线拍| 中国毛片免费观看| 久久久久亚洲精品中文字幕| 国产高清视频免费在线观看| 亚洲精品无码成人片在线观看| 午夜在线免费视频 | 青青草国产免费久久久下载| 亚洲美国产亚洲AV| 国产猛烈高潮尖叫视频免费| 视频一区在线免费观看| 亚洲日韩涩涩成人午夜私人影院| 一个人看的www在线免费视频| 亚洲а∨天堂久久精品9966 | 最近免费mv在线电影| 亚洲小说区图片区| 精品熟女少妇AV免费观看| 亚洲综合精品第一页| 亚洲福利在线播放| 国偷自产一区二区免费视频| 久久亚洲AV成人出白浆无码国产| 麻豆国产精品免费视频| 亚洲色成人网站WWW永久四虎| 免费一级毛片一级毛片aa| 成av免费大片黄在线观看 | 国产gv天堂亚洲国产gv刚刚碰| av永久免费网站在线观看| 亚洲国产日产无码精品| 国产无遮挡又黄又爽免费视频| 国产精品永久免费视频| 久久精品国产亚洲AV香蕉| 大陆一级毛片免费视频观看i| 一级a性色生活片久久无少妇一级婬片免费放| 亚洲一区二区精品视频| 毛片免费全部播放无码| 亚洲AV无码一区二区三区电影 | 四虎成人精品国产永久免费无码| 亚洲AV永久纯肉无码精品动漫| 在线观看无码AV网站永久免费| 在线播放免费人成视频网站|