關於泛型

一直有用到泛型,可是沒有深刻研究其用法,今天遇到一個方法就有點蒙圈,以下:java

public <T extends TransactionBaseService> int aroundTransHelper(T service, Map<String, Object> params, Map<String, Object> container)
        throws Exception {

return 0;app

}ide

後來理解爲<T extends TransactionBaseService>是定義後面的泛型參數(若理解錯了,再來改正).ui

詳細的定義和引用見:http://my.oschina.net/jiemachina/blog/201507.net

還有看到的一篇不錯的blog引用以下:對象

泛型機制經常使用的參數有3個:
「?」表明任意類型。若是隻指定了<?>,而沒有extends,則默認是容許任意類。
extends關鍵字聲明瞭類型的上界,表示參數化的類型多是所指定的類型,或者是此類型的子類。
super關鍵字聲明瞭類型的下界,表示參數化的類型多是所指定的類型,或者是此類型的父類型,直至Object
前提
Fruit是Apple和Orange的超類。
本章經過java代碼逐一分析泛型參數的意義和區別
extends參數:
[java]  
public void extend(List<? extends Fruit> list, Fruit fruit){    
        Fruit now = list.get(0);    
        System.out.println("now==>" + now);  
    //    Apple a = list.get(0);  沒法經過編譯  
        Object o = list.get(0);   
        System.out.println(o);  
        // list.add(fruit); //這句話沒法編譯      
        // list.add(new Object());  // 沒法經過編譯  
        list.add(null);//這句能夠編譯,由於null沒有類型信息    
    }   
在上面的例子中,能夠明確從list中取得的記錄必定是Fruit,可是沒法肯定是Apple,list除了傳入null外,不能添加其餘任何參數;分析緣由前先看如下的例子:
[java] 
public void testExtendType(){  
    List<? extends Fruit> list = new ArrayList<Fruit>();  
    List<? extends Fruit> list2 = new ArrayList<Apple>();  
    List<? extends Fruit> list3 = new ArrayList<Orange>();  
    extend(list2, new Apple());  
}  
從以上代碼能夠看出:
extends關鍵字聲明瞭類型的上界,表示參數化的類型多是所指定的類型,或者是此類型的子類,List<? extends Fruit> 能夠指向 ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>()等。如今若是傳入的參數list爲new ArrayList<Apple>(),則此時你向此list中添加
Fruit,則確定報錯。而讀取數據時,無論list是什麼類型,讀取的數據確定都是Fruit,同時Fruit也是Object。
經過以上的分析,知道直接往繼承extends中的列表中添加記錄是不行的,那麼如何向extends修飾的list中添加記錄,可使用泛型方法來達到目的:
[java]  
public <T extends Fruit> void extendType2(List<T> list, T date){    
        list.add(date);    
    }   
調用示例以下:
[java]  
public void testExtendType2(){    
        List<Apple> list = new ArrayList<Apple>();    
        extendType2(list,new Apple());    
    }  
super參數
super用的很少,只簡單介紹一下。
[java]  
public void superType(List<? super Apple> list, Apple apple){    
        Object o = list.get(0);  
        System.out.println(o);  
    //  Apple a = list.get(0); // 不能編譯  
          
     // Apple apple = list.get(0); // 不能編譯    
        list.add(apple);  
//      list.add( new Object());  // 不能編譯  
//      list.add( new Fruit());  // 不能編譯  
    }    
在以上代碼中,從list中讀取的記錄沒法肯定是任何類型(除Object),list除了添加Apple外,不能添加任何類型的對象(包括Object)。分析緣由前先看如下代碼:
[java]  
public void testSuperType(){    
    List<? super Apple> list = new ArrayList<Apple>();    
    List<? super Apple> list2 = new ArrayList<Fruit>();   
    superType(list2, new Apple());    
}  
super關鍵字聲明瞭類型的下界,表示參數化的類型是所指定的類型,或者是此類型的父類型,直至Object。List<? super Apple > 能夠引用  List<Apple>,也能夠引用 List<Fruit>,因此沒法保證list中都是Apple,可是能夠保證,全部list引用的都是Apple的父類,全部向此列表中添加Apple是沒有問題的,而很顯然你向List<Fruit>、List<Apple>中添加Object、Fruit對象,確定失敗,只可以添加Apple。
?參數
「?」表明任意類型。?能夠看作 ? extends Object 的縮寫。
[java] 
public void wideCardType(List<?> list, Fruit fruit ){  
    Object o = list.get(0);  
    System.out.println(list.get(0));  
    //  list.add(fruit);  // 不能編譯  
    //  list.add(new Object()); // 不能被編譯  
}  
[java]  
public void testWideCardType(){  
        /** 
         * ? 能夠看作 ? extends Object 的簡化版 
         */  
        List<?> list = new ArrayList<Fruit>();  
        List<?> list2 = new ArrayList<Apple>();  
        List<?> list3 = new ArrayList<Object>();  
          
        wideCardType(list,new Fruit());  
    }  
List<? super Object> 能夠引用  List<任何類型>,而Object是全部的對象的祖先,此list只能添加Object類型對象。
extends和super意義記憶的技巧
? extends A: ?繼承A,?是A的子類,或者?是A自己
? super B:    ?是B的父類,或者?是B自己blog

相關文章
相關標籤/搜索