国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

JAVA泛型——逆變

2019-11-14 15:14:59
字體:
來源:轉載
供稿:網友

  在上篇《java泛型——協變》這篇文章中遺留以下問題——協變不能解決將子類型添加到父類型的泛型列表中。本篇將用逆變來解決這個問題。

實驗準備

  我們首先增加以下方法,見代碼清單1所示。

代碼清單1

/**     *      * 描 述:Exp3使用逆變<br/>     * 作 者:jiaan.gja<br/>     * 歷 史: (版本) 作者 時間 注釋 <br/>     * @param itemList     */    public void doDecorate3(List<? super T> itemList, T t) {        for(int i = 0; i < itemList.size(); i++) {            System.out.PRintln(itemList.get(i));        }    }    /**     *      * 描 述:Exp3使用逆變<br/>     * 作 者:jiaan.gja<br/>     * 歷 史: (版本) 作者 時間 注釋 <br/>     * @param itemList     */    public void addDecorate3(List<? super T> itemList, T t) {        itemList.add(t);    }

語法List<? super T>即為Java泛型的逆變,addDecorate3方法中的itemList.add(t)語句也沒有協變出現的編譯問題。

實驗:泛型逆變

  現在我們嘗試下逆變的用途,如代碼清單2所示。

代碼清單2

/** *  * 類 名: Exp3<br/> * 描 述: 泛型的逆變使用<br/> * 作 者: 耿嘉安<br/> * 創 建: 2015年8月25日<br/> * * 歷 史: (版本) 作者 時間 注釋 */class Exp3 {    public static void main(String[] args) {        Decorator<Auction> decoratorA = new Decorator<Auction>();        List<Auction> listA = new ArrayList<Auction>();        Auction auctionOne = new Auction("auctionOne");        Auction auctionTwo = new Auction("auctionTwo");        decoratorA.addDecorate3(listA, auctionOne);        decoratorA.addDecorate3(listA, auctionTwo);        decoratorA.doDecorate3(listA);                Decorator<Table> decoratorB = new Decorator<Table>();        List<Table> listB = new ArrayList<Table>();        Table tableOne = new Table("tableOne", 10);        Table tableTwo = new Table("tableTwo", 20);        decoratorB.addDecorate3(listB, tableOne);        decoratorB.addDecorate3(listB, tableTwo);        decoratorB.doDecorate3(listB);                Decorator<Service> decoratorC = new Decorator<Service>();        List<Service> listC = new ArrayList<Service>();        Service serviceOne = new Service("serviceOne", "methodOne");        Service serviceTwo = new Service("serviceTwo", "methodTwo");        decoratorC.addDecorate3(listC, serviceOne);        decoratorC.addDecorate3(listC, serviceTwo);        decoratorC.doDecorate3(listC);                /**         * 測試逆變開始         */        decoratorA.doDecorate3(listB);        decoratorA.doDecorate3(listC);            }}

 我們發現以下兩條語句都會編譯出錯:

        decoratorA.doDecorate3(listB);        decoratorA.doDecorate3(listC);

我們暫且將這個問題放一放,將它們暫時注釋掉,增加代碼清單3中的代碼。

代碼清單3

        List<Object> listD = new ArrayList<Object>();                decoratorA.doDecorate3(listD);        decoratorA.doDecorate3(listA);        decoratorA.doDecorate3(listB);        decoratorA.doDecorate3(listC);        decoratorB.doDecorate3(listD);        decoratorB.doDecorate3(listA);        decoratorB.doDecorate3(listB);        decoratorB.doDecorate3(listC);        decoratorC.doDecorate3(listD);        decoratorC.doDecorate3(listA);        decoratorC.doDecorate3(listC);        decoratorC.doDecorate3(listB);    

 

代碼清單3中,decoratorA.doDecorate3(listB);decoratorA.doDecorate3(listC);decoratorB.doDecorate3(listC);decoratorC.doDecorate3(listB);這四條語句編譯錯誤,這說明如下聲明是允許的:

List<? super Auction> itemList = new ArrayList<Object>();List<? super Auction> itemList = new ArrayList<Auction>();List<? super Table> itemList = new ArrayList<Object>();List<? super Table> itemList = new ArrayList<Auction>();List<? super Table> itemList = new ArrayList<Table>();List<? super Service> itemList = new ArrayList<Object>();List<? super Service> itemList = new ArrayList<Auction>();List<? super Service> itemList = new ArrayList<Service>();

 

而下面這樣是不允許的:

List<? super Auction> itemList = new ArrayList<Table>(); List<? super Auction> itemList = new ArrayList<Service>(); List<? super Table> itemList = new ArrayList<Service>(); List<? super Service> itemList = new ArrayList<Table>();

現在我們編寫以下代碼:

        List<? super Auction> itemList = listA;        Object o = itemList.get(0);        Auction a = itemList.get(0);        Table t = itemList.get(0);        Service s = itemList.get(0);        itemList = listD;        o = itemList.get(0);        a = itemList.get(0);        t = itemList.get(0);        s = itemList.get(0);    

上述代碼中,除了從itemList獲取Object的語句之外,都會編譯出錯,這是為什么?因為itemList有可能是一個ArrayList<Object>,所以轉型為Auction是可能錯誤的。itemList可能是ArrayList<Object>或者ArrayList<Auction>,所以轉型為Table或者Service必然是不對的。

最后我們增加以下代碼:

        itemList.add(new Auction("auctionThr"));        itemList.add(new Service("serviceThr", "methodThr"));        itemList.add(new Table("tableThr", 10));

上述代碼沒有問題,因為不論itemList是ArrayList<Object>或者ArrayList<Auction>,向其中添加Auction、Table、Service都符合最初的原則。

假如向itemList添加Object是編譯失敗的,因為itemList可能是ArrayList<Auction>。

總結

如果向泛型中添加子類,可以使用逆變來實現。如果要從泛型中獲取子類,逆變有轉型錯誤,此時應該使用協變。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 和林格尔县| 镇巴县| 馆陶县| 台东县| 江口县| 广饶县| 什邡市| 河西区| 临沧市| 静乐县| 汝南县| 成安县| 曲水县| 呼伦贝尔市| 醴陵市| 锦屏县| 平远县| 武鸣县| 龙口市| 沈丘县| 彝良县| 常山县| 琼海市| 肥东县| 东源县| 新巴尔虎右旗| 鹤壁市| 高安市| 四会市| 阿拉善左旗| 花莲县| 调兵山市| 大丰市| 松原市| 北碚区| 福鼎市| 师宗县| 车险| 长汀县| 莒南县| 稻城县|