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

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

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

    JDK 1.5引入的新特性 -- 泛型

    1. 引言

    JDK 1.5 中引入了新的語言成分, 泛型(Generics)是其中較為重要的一個(gè).
    簡(jiǎn)單的泛型(Defining Simple Generics)

    以下代碼摘自java.util包的List接口和Iterator接口的定義:

    public interface List<E> {
    ? void add(E x);
    ? Iterator<E> iterator();
    }
    public interface Iterator<E> {
    ? E next();
    ? boolean hasNext();
    }

    類型參數(shù)

    與尖括號(hào)有關(guān)的一些東西是JDK 5引入的新東西, 它們是List和Iterator接口的"形式的類型參數(shù)"(簡(jiǎn)稱"類型形參")聲明.
    而在對(duì)泛型聲明List進(jìn)行調(diào)用時(shí)(例如: List<Integer>), 所有出現(xiàn)的類型形參(如
    E)的地方, 都會(huì)被"實(shí)際的類型參數(shù)"(簡(jiǎn)稱"類型實(shí)參", 如 Integer)所替換掉.

    雖然與C++中的模板機(jī)制在形式上很想像, 但必需注意, Java中的泛型聲明決不會(huì)在調(diào)用時(shí)被展成多份副本: 不論是在源碼級(jí), 二進(jìn)制級(jí), 還是在磁盤或內(nèi)存中, 都不會(huì)被展開!

    泛型聲明只會(huì)也只需編譯一次, 并生成一個(gè)類文件(class文件), 這一點(diǎn)跟普通的類或接口完全一樣.

    類型參數(shù)其實(shí)跟方法或構(gòu)造器中所用的通常參數(shù)相類似. 一個(gè)方法中可以聲明它用以處理的"形式的值參數(shù)", 相似地, 泛型聲明也有其"形式的類型參數(shù)"; 當(dāng)方法被調(diào)用時(shí), 實(shí)際參數(shù)會(huì)替換形式參數(shù), 然后執(zhí)行方法體, 同樣, 當(dāng)泛型聲明被調(diào)用時(shí), 實(shí)際的類型參數(shù)會(huì)替換掉形式的類型參數(shù).

    關(guān)于命名約定的備注: 推薦使用精煉而簡(jiǎn)明(如, 單個(gè)字符)的方式為形式的類型參數(shù)命名. 最好避免使用小寫字符, 以便與普通的類或接口的參數(shù)相區(qū)分開來. 許多宣傳品類型使用 E 表示其元素的類型形參.


    2. 泛類型與子類型化(Generics and Subtyping)

    先看以下兩行代碼是否合法:
    List<String> ls = new ArrayList<String>(); // 1
    List<Object> lo = ls; // 2
    第一行沒問題, 關(guān)鍵在第二行代碼, 大多數(shù)人會(huì)認(rèn)為, "一個(gè)String的List自然更是一個(gè)Object的List", 因此, 第2行沒問題.

    好, 接著看以下代碼:
    lo.add(new Object()); // 3
    String s = ls.get(0); // 4: 試圖將一個(gè)Object賦給一個(gè)String!

    可見, 通過別名lo, 我們能對(duì)ls, 一個(gè)String的列表, 進(jìn)行數(shù)據(jù)操作(特別是插入一個(gè)Object), 從而導(dǎo)致ls不僅僅是容納了String對(duì)象! 這是Java編譯器不容許的! 編譯時(shí), 第2行會(huì)報(bào)告一個(gè)編譯錯(cuò)誤的.

    通常, 若Foo是Bar的一個(gè)子類型(子類或子接口), G是某個(gè)泛型聲明, 則G<Foo>并不是G<Bar>的一個(gè)子類型.

    這一點(diǎn)往往是最難以理解的, 因?yàn)樗屯ǔ5闹庇^相左. 在直觀的理解中, 我們實(shí)際上假定了集合是不會(huì)變動(dòng)的, 但java語言中則非如此.


    3. 通配(Wildcards)

    假定要輸出一個(gè)集合中的所有元素. 以下分別是舊版本及新版本(JDK 1.5)中的寫法:

    void printCollection(Collection c) {
    ? Iterator i = c.iterator();
    ? for( k = 0; k < c.size(); k++) {
    ??? System.out.println( i.next() );
    }}

    void printCollection(Collection<Object> c) {
    ? for(Object e : c) {
    ??? System.out.println(e);
    }}

    問題在于, 新版本反而不如舊版本更有用些. 因?yàn)榕f版本能使用各種類型的集合作為參數(shù), 但新版本則只能使用Collection<Object>. 而正如上節(jié)看到的, Collection<Object>并不是其它各種集合的超類型(父類型).

    所有集合的超類型應(yīng)該寫作: Collection<?>, 讀作: collection of unknown(未知集合), 即一個(gè)集合, 其元素類型可以與任何類型相匹配. 因此稱這種類型為"通配類型".

    正確實(shí)現(xiàn)上述舊版本的代碼可以這么寫:
    void printCollection(Collection<?> c) {
    ? for(Object e : c) {
    ??? System.out.println(e);
    }}

    這時(shí), 可以用任意類型的集合來調(diào)用此方法. 注意在方法體中, 仍然從 c 中讀入元素并賦給了Object, 這是沒有錯(cuò)誤的, 因此不論類型實(shí)參是何種集合, 它的元素都是object. 然而, 如果任意給它增加一個(gè)object則是不安全的:

    Collection<?> c = new ArrayList<String>();
    c.add(new Object()); // 編譯時(shí)的錯(cuò)誤

    由于我們不知道c的元素類型是什么, 所以不能給它增加一個(gè)object. 方法add()接受一個(gè)類型E的參數(shù), 而E與集合的元素類型相同. 當(dāng)類型實(shí)參是?時(shí), 它表示"未知的類型", 我們傳遞給add的參數(shù)必須是這個(gè)"未知類型"的子類型. 不幸的是, 既然類型未知, 也就無法決定其子類型, 于是什么也不能作為其參數(shù). 唯一的例外是null, 因?yàn)閚ull是所有類型的一個(gè)成員.

    另一方面, 如果給了一個(gè)List<?>, 我們可以調(diào)用get()方法并使用其返回的元素. 雖然返回的元素類型是"未知類型", 但它總歸是一個(gè)object, 因此將get()返回的元素賦給一個(gè)Object類型的變量, 或?qū)⑵鋫鬟f給一個(gè)可接受Object的參數(shù)都是安全的.

    posted on 2006-11-20 15:44 Timothy 閱讀(334) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA大本營(yíng)

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計(jì)

    公告

    語義Web : 網(wǎng)絡(luò)就是計(jì)算機(jī),軟件就是服務(wù)!

    常用鏈接

    留言簿(4)

    隨筆檔案(20)

    文章分類(25)

    文章檔案(25)

    新聞分類(4)

    新聞檔案(4)

    相冊(cè)

    收藏夾(27)

    個(gè)人主頁

    網(wǎng)絡(luò)博客

    最新隨筆

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 日韩免费视频播放| 亚洲色图古典武侠| 免费无码毛片一区二区APP| 亚洲最大中文字幕| 国产小视频在线免费| 国产精品免费αv视频| 亚洲国产精品一区| 国产成人免费A在线视频| 久久青草91免费观看| 亚洲精品无码不卡在线播放| 久久久久亚洲精品天堂久久久久久| 最近2019年免费中文字幕高清| 亚洲丶国产丶欧美一区二区三区| 久久精品国产69国产精品亚洲| 9久9久女女免费精品视频在线观看| jizz18免费视频| 精品亚洲AV无码一区二区三区 | 亚洲性线免费观看视频成熟| 亚洲中文无韩国r级电影| 无码国产精品一区二区免费式影视 | 国产亚洲成av人片在线观看| 女人18毛片a级毛片免费视频| 久久精品免费一区二区三区| 久久精品亚洲日本波多野结衣| 亚洲免费精彩视频在线观看| 亚洲国产精品综合久久网络| 国产1024精品视频专区免费| 久久福利青草精品资源站免费| 日韩在线观看视频免费| 中文文字幕文字幕亚洲色| 亚洲AV中文无码字幕色三| 亚洲AV无码成H人在线观看| 成在人线AV无码免费| 免费看男人j放进女人j免费看| 国产亚洲精品美女| 亚洲一区二区三区成人网站| 91亚洲导航深夜福利| 久久九九亚洲精品| 91麻豆国产自产在线观看亚洲| 国产美女被遭强高潮免费网站| 99久久久精品免费观看国产|