<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>的形式,否則的話,編譯器會認為你的行為不正?;蚴呛芪kU,所以給你一個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://www.tkk7.com/dedian/archive/2006/06/23/54615.html  回復  更多評論
      

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

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

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

    免得給自己找麻煩。

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

      回復  更多評論
      

    主站蜘蛛池模板: 亚洲国产V高清在线观看| 中文字幕在线观看免费视频 | 国产精品永久免费10000| 国产亚洲av片在线观看16女人| 污污视频网站免费观看| 日韩毛片无码永久免费看| 国产亚洲精品AAAA片APP| 国产一级理论免费版| 日韩免费在线中文字幕| 亚洲乱码国产一区网址| 成年免费a级毛片免费看无码| 久久久久亚洲av毛片大| 日韩精品无码免费专区网站| 久久亚洲成a人片| 精品无码AV无码免费专区| 亚洲日韩乱码中文无码蜜桃| 青娱乐免费在线视频| 亚洲成AV人影片在线观看| 亚洲av无码成人精品区在线播放 | 毛片a级毛片免费观看品善网| 亚洲狠狠色丁香婷婷综合| 免费成人午夜视频| 国产综合免费精品久久久| 亚洲美女视频一区二区三区| 免费大片黄在线观看yw| 亚洲av日韩av永久在线观看 | 曰批视频免费40分钟试看天天| 亚洲午夜一区二区电影院| 国产一区在线观看免费| a级毛片毛片免费观看久潮| 亚洲综合久久久久久中文字幕| 四虎影院免费在线播放| 国产成人高清精品免费观看| 99久久精品国产亚洲| 在线免费一区二区| 免费精品99久久国产综合精品| 亚洲人成综合网站7777香蕉| 免费A级毛片无码久久版| 亚洲免费在线播放| 粉色视频成年免费人15次| 亚洲AV第一页国产精品|