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

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

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

    John Jiang

    a cup of Java, cheers!
    https://github.com/johnshajiang/blog

       :: 首頁 ::  :: 聯(lián)系 :: 聚合  :: 管理 ::
      131 隨筆 :: 1 文章 :: 530 評論 :: 0 Trackbacks
    在泛型中使用通配符和繼承
        本文是Sun官方以Blog形式發(fā)布的Java核心技術(shù)竅門(JavaCoreTechTip)中的一篇,它以非常簡潔的示例展示了泛型通配符的使用,初學(xué)Java泛型的朋友可以看看。(2009.12.30最后更新)
        Java2平臺,標(biāo)準(zhǔn)版5.0(J2SE 5.0)為Java程序設(shè)計語言及其平臺引入了泛型。在最簡單的案例和典型的應(yīng)用中,泛型能夠識別集合容器中所存儲的是否是你所期望的對象。所以,你可以特別說你有一個String或其它類型對象的List,而不是聲稱你的程序有一個Object的List。所以,如果你不小心向該List中加入了錯誤類型的對象,編譯器會告之你這個錯誤。該錯誤將在編譯時進行修復(fù),而不用等到你運行該程序,且在程序運行到該處代碼時,在獲取對象的操作中產(chǎn)生一個運行時的強制類型轉(zhuǎn)換異常。
    這就提出了泛型的第二個好處。迭代器將變得類型安全了。Iterator接口中的next()方法將會返回集合中下一個元素的類型安全版本。
        但這并不是本文要介紹的泛型應(yīng)用的竅門,那些竅門已由2005 Core Java Technologies Tip描述過了。在使用泛型時,大多數(shù)人都不能很好地理解對extends關(guān)鍵字的使用。一個典型的描述如何使用extends關(guān)鍵字的示例與繪制圖形有關(guān)。與其不同的是,此處竅門所用的示例將使用Swing組件,以便你不必創(chuàng)建額外的新類。在一個非常有限的例子中,Swing按鈕組件的類層次結(jié)構(gòu)如下所示,當(dāng)然,Object是實際上的根。
    Component
    |- Container
       
    |- JComponent
          
    |- AbstractButton
             
    |- JButton
             
    |- JMenuItem
                
    |- JCheckBoxMenuItem
                
    |- JMenu
                
    |- JRadioButtonMenuItem
             
    |- JToggleButton
                
    |- JCheckBox
                
    |- JRadioButton

        所有AbstractButton的子類都共同享有的一個東西就是方法getText。這就是泛型的精髓,你能定義一個方法去處理以AbstractButton為元素的List,并返回這些按鈕的String類型的標(biāo)簽的List。下面是該方法的第一個版本:
    public static List<String> getLabels(List<AbstractButton> list) {
        List
    <String> labelList = new ArrayList<String>(list.size());
        
    for (AbstractButton button: list) {
            labelList.add(button.getText());
        }
        
    return labelList;
    }

        下面就是如何使用該方法。首先,定義一個AbstractButton類型的List,然后向其中填充值,并調(diào)用該方法:
    List<AbstractButton> buttonList = new ArrayList<AbstractButton>();
    buttonList.add(
    new JButton("Hello"));
    buttonList.add(
    new JCheckBox("World"));
    buttonList.add(
    new JRadioButton("Hola"));
    buttonList.add(
    new JMenuItem("Mundo"));

    List labels 
    = getLabels(buttonList);
    System.out.println(labels);

        根據(jù)Google,"Hola, Mundo"是"Hello, World"的西班牙譯文。調(diào)用println()方法的結(jié)果如下所示:
    [Hello, World, Hola, Mundo]

        對于AbstractButtonList對象,一切都能正常運行,但當(dāng)是其它類型,特別是AbstractButton子類型的List時,就不能正常工作了。從邏輯上,有人可能認(rèn)為對于以JButton為元素的List,一切仍能正常工作。因為JButton是AbstractButton的子類。難道不能對AbstractButton子類型的List調(diào)用方法getLabels(List<AbstractButton>)
    然而,事實并非如此。因為這是一個編譯時檢查,同時也因為getLabels方法被定義為只接受AbstractButton的List,你不能向該方法中傳入任何其它類型的List。
    GetList.java:13: getLabels(java.util.List<javax.swing.AbstractButton>)
      in GetList cannot be applied to (java.util.List
    <javax.swing.JButton>)

        List
    <String> labels = getLabels(buttonList);
                              
    ^
    1 error

    這也就是extends關(guān)鍵字發(fā)揮作用的地方了。不將getLabes方法定義為僅僅接受AbstractButton List,而是將它定義為接受AbstractButton子類的List
    public static List<String> getLabels(
            List
    <? extends AbstractButton> list)

    此處的通配符?表明該方法并不關(guān)心確切的類型是什么,只要它是AbstractButton的子類型即可。下面是綜合了前述所有代碼片斷的完整示例程序:
    import java.util.*;
    import javax.swing.*;

    public class GetList {
        
    public static void main(String args[]) {
            List
    <JButton> buttonList =
                    
    new ArrayList<JButton>();
            buttonList.add(
    new JButton("Hello"));
            buttonList.add(
    new JButton("World"));
            buttonList.add(
    new JButton("Hola"));
            buttonList.add(
    new JButton("Mundo"));

            List labels 
    = getLabels(buttonList);
            System.out.println(labels);
        }

        
    public static List<String> getLabels(
                List
    <? extends AbstractButton> list) {
            List
    <String> labelList = new ArrayList<String>(list.size());
            
    for (AbstractButton button: list) {
                labelList.add(button.getText());
            }
            
    return labelList;
        }
    }

    現(xiàn)在,當(dāng)你要用泛型來定義你自己的類和方法時,就要考慮接受作為泛型參數(shù)的抽象類,或它的任一超類,記得使用通配符以便相同的方法對于子類也能很好地工作。
    更多關(guān)于泛型的信息,請見兩篇較早前由Gilad Bracha撰寫的教程:一篇是2004年的教程(PDF),另一篇是在線的Java Tutorial中的泛型章節(jié)。

    posted on 2009-12-28 13:44 John Jiang 閱讀(2102) 評論(0)  編輯  收藏 所屬分類: JavaSEGenericsJava翻譯CoreJavaTechTips
    主站蜘蛛池模板: 色噜噜亚洲男人的天堂| 亚洲成AV人片一区二区密柚| a毛片基地免费全部视频| 在线观看特色大片免费视频| 亚洲精品第一国产综合精品| 日韩亚洲国产高清免费视频| 一级毛片大全免费播放| 亚洲精品免费视频| 超pen个人视频国产免费观看| 国产AV无码专区亚洲AV漫画 | 精品国产亚洲男女在线线电影| 亚洲三级电影网址| 亚洲aⅴ无码专区在线观看春色| 野花香在线视频免费观看大全| 99热在线精品免费全部my| 亚洲不卡影院午夜在线观看| 精品国产免费一区二区| 污网站在线观看免费| 国产高清不卡免费在线| 国产又黄又爽又猛的免费视频播放| 亚洲AV无码第一区二区三区| 污污视频网站免费观看| 自拍偷自拍亚洲精品被多人伦好爽 | 亚洲国产综合第一精品小说| 国产精品永久免费| 国产精品久久免费视频| 日本在线观看免费高清| 国产V亚洲V天堂A无码| 色老头永久免费网站| 亚洲成AV人在线观看天堂无码| 亚洲免费在线视频播放| 亚洲欧美国产日韩av野草社区| 一区二区免费视频| 亚洲午夜精品久久久久久app| 可以免费看黄视频的网站| 久久久亚洲欧洲日产国码二区| 三级毛片在线免费观看| 国产成人免费一区二区三区| 你懂的免费在线观看| 精品亚洲一区二区三区在线播放| 三年片在线观看免费观看大全一 |