黑馬程序員——泛型

一、泛型類
自Java1.5版本泛型出現,集合類應該是被重新書寫了,由普通類改寫成了泛型類。
泛型類的使用過程包括的步驟有:泛型類引用的聲明,泛型類對象的創建以及引用指向對象。作此說明是爲了下面方便說明我對泛型類的理解。
1.聲明泛型類引用時,需在類名後指出泛型指代的類型,注意我說的是指出,不是指明。這裏指出的意思是有<…>這組符號,放個”?”或”?
extends(super) XXX”也算指出了。如果不指出,也可以編譯運行,並且未做出指出的泛型可以指代任意類型,但會有警告。集合類(泛型版本)就表現出這個特性了。
舉例:(String只是舉例)
MyClass<String> mc;    //可編譯運行,無警告,mc中相應的泛型只能使用String
MyClass     mc;         //可編譯運行,有警告,mc中相應的泛型可以指代任意類型

2.創建泛型類對象時,需要在類名後指明泛型指代的類型,注意這裏我說的是指明,”?”或”? extends(super) XXX”不算指明。就是有<String>,尖括號中的泛型必須具體到某一種類型。如果不指出也會有警告,但同樣也能編譯運行,並且未指出的泛型可以指代任意類型,但如果指出了卻未指明,即”?”或”? extends(super) XXX”,就不是警告了,而是錯誤。
舉例:(String只是舉例)
new MyClass<String>();     //可編譯運行,無警告,其中相應的泛型只能使用String
new MyClass();     //可編譯運行,有警告,其中相應的泛型可以指代任意類型
new       MyClass<?>();             //錯誤。

3.泛型引用指向泛型對象,
      1)未指出泛型類型的引用,可以指向泛型類型被指明爲任意類型的泛型對象,即“MyClass mc; ” 聲明的mc可以指向new MyClass()   ,new MyClass< XXX>(),  XXX可以爲具體到某一種類型的任意類型。
      2)MyClass<String> mc; 聲明的mc只能指向new MyClass(),new MyClass< String >(),
在這裏,new MyClass() 被自動轉換成了String,此轉換是未經檢查的,
當new MyClass()不是String類型時,一旦調用mc的String方法時,就會拋出轉換異常。
      3) MyClass<?> mc;  中的mc可以指向的泛型類和“MyClass mc; ”中的mc可以指向的類型一樣,只是這樣聲明不會出現警告。
      4)MyClass<? extends  Father> mc; 聲明的mc可以指向new MyClass() 和new  MyClass<XXX >(),  XXX是Father及其子類中具體到某一種的類。
在這裏,new MyClass()被自動轉換成了Father(eclipse中寫的是轉換成“? extends  Father”,但給出的方法只是Father的方法。此轉換是未經檢查的,
當new MyClass()不是Father類型時,一旦調用mc的Father方法時,就會拋出轉換異常。
      5)MyClass<? super Father>  mc;  同4)相似,只是XXX是Father及其父類。

      關於引用指向對象:
1)MyClass<? extends  Father> mc =new MyClass<Son>();   是mc指向了後面創建的對象;
2)另一種情況,定義方法:
Void  show(MyClass<?  extends Father>   mc){}   這裏也是聲明瞭一個引用,當使用該方法時,就是讓這個引用指向了相應的對象,所以在使用該方法時,其中的參數mc只能是上面4)所包括的類型。
舉例:
ArrayList的一個構造方法的定義:ArrayList(Collection<? extends Father>  c){…}  該構造方法用到的Father是定義ArrayList<E>時其中的E。
下面是該方法的使用即調用該構造方法創建一個ArrayList:
Student和Worker均是Person的子類:
1                ArrayList<Student> slis=new ArrayList<Student>();
2                LinkedList<Worker> wlis=new LinkedList<Worker>();
3                ArrayList<Person> plis1=new ArrayList<Person>(slis);
4                ArrayList<Person> plis2=new ArrayList<Person>(wlis);
5                ArrayList<String> ms=new ArrayList<String>();                                        //String不是Person的子類
6//                ArrayList<Person> plis3=new ArrayList<Person>(ms);               
7                LinkedList<Object> mo=new LinkedList<Object>();                                //Object是Person的父類,但此處要子類
8//                ArrayList<Person> plis4=new ArrayList<Person>(mo);
第3行和第4行定義ArrayList時,用了上面的構造方法,其中的E是Person,所以括號中的Collection<...>中的泛型必須是Person或其子類,正如第1行和第2行定義的,slis中的Student和wlis中的Worker都是Person的子類,所以第3和第4行沒問題;但是第6行和第8行會出錯,因爲String和Object都不是Person的子類。
二、泛型方法
在定義方法時,在返回值前面加上<T>,T表示泛型符號,在該方法中可以用T表示一種尚不確定的類型,可以在方法參數列表和方法內部使用。
如:
......
public <T> puts(T t){
System.out.println(t)
}
public <T> put(T t){
System.out.print(t)
}
......
此代碼以泛型的形式實現了對該方法傳入類型的重載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章