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

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

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

    e代劍客——溫柔一刀

    生活就像海洋,只有意志堅強的人,才能到達彼岸

       :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      76 隨筆 :: 7 文章 :: 215 評論 :: 0 Trackbacks
    1.一個簡單的范型示例

    在以前,你可能遇到過這樣的代碼:

    1List?list?=?new?LinkedList();?
    2
    3list.add("a");?
    4
    5list.add("b");?
    6
    7list.add("c");?
    8
    9String?name?=?(String)list.iterator.next();?

    注意,第三行需要強制轉換。而使用范型:
    ?1
    ?2List<String>?list?=?new?LinkedList<String>();?
    ?3
    ?4list.add("a")?
    ?5
    ?6list.add("b");?
    ?7
    ?8list.add("c");?
    ?9
    10String?name?=?list.iterator.next();?
    11
    12

    這里將list聲明成String類型的List。List是有一個類型參數的范型接口。這個例子中類型參數是String。

    ?
    2.定義簡單的范型

    看j2se5.0中List和Iterator接口的實現(片斷):
    ?1
    ?2public?interface?List<E>??
    ?3
    ?4{??
    ?5
    ?6void?add(E?x);?
    ?7
    ?8Iterator<E>?iterator();?
    ?9
    10}
    ?
    11
    12public?interface?Iterator<E>??
    13
    14{??
    15
    16E?next();?
    17
    18boolean?hasNext();?
    19
    20}
    ??
    21
    22

    上面的代碼我們比較熟悉,但是其中增加了尖括號。尖括號中的內容定義了接口List和Iterator的形式類型參數。類型參數可以用在范型聲明中,如類和接口的聲明。

    一旦聲明了范型,你就可以使用它。在上面的例子中使用了List<String>。這里使用String是實參,代替了形參E。如果使用List<Integer>,則用實參Integer代替了形參E。

    不管List<Integer>還是List<String>,它們的類只有一個。考慮下面的代碼:
    1
    2List<String>?list1?=?new?LinkedList<String>();?
    3
    4List<Integer>?list2?=?new?LinkedList<Integer>();?
    5
    6System.out.println(list1.getClass()==list2.getClass());?
    7
    ?

    輸出結果為true。

    ?

    一般來說,形式類型參數都是大寫,盡量使用單個字母,許多容器類都使用E作為參數。

    ?

    3.范型和繼承

    考慮下面的代碼,你認為它會出錯嗎?

    1
    2String?s?="?xxx@gmail.com";?
    3
    4Object?o?=?s:?
    5

    當然,String類繼承Object類,這樣做不會出錯。但下面的代碼呢?

    1List<String>?s?=?new?LinkedList<String>();?
    2
    3List<Object>o=s;?
    4


    編譯出錯!

    是的,List<Object>和List<String>沒有繼承關系。

    ?

    4.通配符

    考慮下面一個方法:

    ?1
    ?2public?void?printCollection(Collection<Object>?c)?
    ?3
    ?4{?
    ?5
    ?6???for(Object?o:c)?
    ?7
    ?8{?
    ?9
    10???System.out.printf("%s%n",o);?
    11
    12}
    ?
    13
    14}
    ?
    15


    事實上,上面這個方法并不通用,它只能打印Collection<Object>類型的集合,象其他的如Collection<String>、Collection<Integer>并不能被打印,因為對象類型不一致。

    為了解決這個問題,可以使用通配符:
    ?1
    ?2public?void?printCollection(Collection<>?c)?
    ?3
    ?4{?
    ?5
    ?6???for(Object?o:c)?
    ?7
    ?8{?
    ?9
    10???System.out.printf("%s%n",o);?
    11
    12}
    ?
    13
    14}
    ?
    15
    16

    Collection<?>被稱作未知類型的集合。問號代表各種類型。

    上面的讀取集合中的數據時,我們采用Object類型。這樣做時可以的,因為不管未知類型最終代表何種類型,它的數據都繼承Object類,那么再考慮一下下面的代碼:
    1
    2Collection<?>?c?=?new?ArrayList<String>();?
    3
    4c.add(new?Object());???
    5
    6

    這樣做時錯誤的,因為我們不知道?代表何種類型,所以我們不能直接將Object增加到集合中,這會出現類型不匹配的情況。
    ?

    5.有限制的通配符

    考慮下面的代碼
    ?1
    ?2class?Man?
    ?3
    ?4{?
    ?5
    ?6???public?String?name?="";?
    ?7
    ?8}
    ?
    ?9
    10class?GoodMan?extends?Man?
    11
    12{?
    13
    14???public?String?name?=?"";?
    15
    16}
    ?
    17
    18class?BadMan?extends?Man?
    19
    20{?
    21
    22???public?String?name?=?"";?
    23
    24}
    ?
    25
    26

    考慮下面的范型方法:
    ?1
    ?2public?void?printName(List<Man>?men)?
    ?3
    ?4{?
    ?5
    ?6???for(Man?man:men)?
    ?7
    ?8???{?
    ?9
    10??????System.out.println("姓名:"+?man.name);?
    11
    12???}
    ?
    13
    14}
    ?
    15
    16


    這個范型方法只能顯示List<Man>類型的數據,下面的代碼允許顯示Man和它的子類。
    ?1
    ?2public?void?printName(List<??extends??Man>?men)?
    ?3
    ?4{?
    ?5
    ?6???for(Man?man:men)?
    ?7
    ?8???{?
    ?9
    10??????System.out.println("姓名:"?+?man.name);?
    11
    12???}
    ?
    13
    14}
    ?
    15
    16

    這里使用??extends?Man代替Man,表明接受任何Man的子類做為參數。

    和前面的代碼類似,下面的代碼也是不正確的:
    ?1
    ?2public?void?adman(List<??extends?Man>?men)?
    ?3
    ?4{?
    ?5
    ?6???GoodMan?good?=?new?GoodMan();?
    ?7
    ?8???good.name?=?"zhupan";?
    ?9
    10???men.add(good);?
    11
    12}
    ?
    13
    14

    原因也很簡單,因為?代表一切繼承Man的類,你并不能保證就一定時GoodMan類。

    ?

    和這種用法類似:
    ?1
    ?2public?void?adman(List<??super?GoodMan>?men)?
    ?3
    ?4{?
    ?5
    ?6???GoodMan?good?=?new?GoodMan();?
    ?7
    ?8???good.name?=?"zhupan";?
    ?9
    10???men.add(good);?
    11
    12}
    ?
    13

    6.范型方法

    考慮下面的代碼,我們將一個數組的內容加到一個集合中
    ?1
    ?2public??void?copyArrayToCollection(Man[]?men,?Collection<?>c)?
    ?3
    ?4{?
    ?5
    ?6for(Man?man:men)?
    ?7
    ?8{?
    ?9
    10???c.add(man);?
    11
    12}
    ?
    13
    14}
    ?
    15
    16

    這段代碼時錯的!

    因為我們并不知道集合C的類型,所以不能將Man類型的數據加到集合中。

    可以使用范型方法解決:
    ?1
    ?2public?<T>?void?copyArrayToCollection(T[]?men,?Collection<T>c)?
    ?3
    ?4{?
    ?5
    ?6for(T?man:men)?
    ?7
    ?8{?
    ?9
    10???c.add(man);?
    11
    12}
    ?
    13
    14}
    ?
    15

    這里T時一個形式類型參數。

    何時該采用通用方法?何時該采用通配符?

    考慮下面的例子:
    ?1
    ?2interface??Collection<E>?
    ?3
    ?4{?
    ?5
    ?6??public?boolean?containsAll(Collection<?>?c);?
    ?7
    ?8public?boolean?addAll(Collection<??extends?E>?c);?
    ?9
    10}
    ?
    11
    12

    改寫成通用方法
    ?1
    ?2interface??Collection<E>?
    ?3
    ?4{?
    ?5
    ?6???public?<T>?boolean?containsAll(Collection<T>?c);?
    ?7
    ?8public?<T?extends?E>?boolean?addAll(Collection<T>?c);?
    ?9
    10}
    ?
    11
    12

    然而,在這里每個方法T只使用了一次,返回值不依賴形式參數,其他參數也不依賴形式參數。這說明實參被用作多態,這種情況下就應該用通配符。
    posted on 2006-08-14 10:16 溫柔一刀 閱讀(639) 評論(1)  編輯  收藏 所屬分類: java相關

    評論

    # re: java 范型編程 2006-08-14 10:31 testtesttest
    test  回復  更多評論
      

    聯系偶 zhupanjava@gmail.com 溫柔一刀
    主站蜘蛛池模板: 三年片在线观看免费观看大全一| 无遮免费网站在线入口| 久久精品视频亚洲| 免费观看国产网址你懂的| 亚洲av无码专区国产不乱码 | 黄色片在线免费观看| 国产精品观看在线亚洲人成网| 国产V亚洲V天堂无码久久久| 国产一卡二卡四卡免费| 日韩免费高清一级毛片| 亚洲黄色一级毛片| 亚洲黄片毛片在线观看| 久草免费在线观看视频| 亚洲阿v天堂在线2017免费| 亚洲午夜电影在线观看| 超清首页国产亚洲丝袜| 中文字幕影片免费在线观看| 男女拍拍拍免费视频网站| 亚洲 日韩经典 中文字幕 | 人人狠狠综合久久亚洲婷婷| 麻豆最新国产剧情AV原创免费 | 久久99青青精品免费观看| 亚洲国产精品久久久久秋霞小| 久久精品亚洲综合| 亚洲AV无码一区二区三区在线观看| 每天更新的免费av片在线观看| 一级做a爰片久久免费| 亚洲欧洲日韩极速播放| 久久亚洲AV午夜福利精品一区| 亚洲AV无码乱码精品国产| 国产成人免费爽爽爽视频 | 久久亚洲国产精品五月天婷| 在线观看人成网站深夜免费| 免费A级毛片无码视频| 丰满人妻一区二区三区免费视频 | 黄页网站在线观看免费高清| 国产高清不卡免费视频| 国产成人自产拍免费视频| 美女被暴羞羞免费视频| 在线亚洲午夜片AV大片| 亚洲制服在线观看|