有關於泛型

目錄
一、泛型的意義
二、泛型類型怎麼編譯的?
三、泛型的上界:(泛型沒有下界)
四、通配符?:
五、注意:

對於泛型,如果我們拿Object去寫的話,並不通用,就比如你寫一個棧,拿到返回值必須強轉(從Object強轉到你想要的類型),如果有多個返回值,那就得強轉多次,所以這個方法行不通,於是引入了泛型:
一、泛型的意義
1、可以對類型進行自動檢查 : 檢查並不是替換(編譯期間進行檢查,放入元素的時候檢查)
2、可以自動對類型進行轉換 :轉換也不是替換(拿出元素的時候自動轉換)

T:類型佔位符 表示該類是一個泛型類

二、泛型類型怎麼編譯的?
類型的擦除機制: 擦除到Object(向上擦除),在編譯器編譯期間把泛型全部擦除爲Object類型

三、泛型的上界:(泛型沒有下界)
class GenericAlg<T extends Comparable> {
public T findMaxVal(T[] array) { //找到數組中的最大值
T max = array[0];
for (int i = 0; i < array.length; i++) {
if(array[i].compareTo(max) > 0) {
max = array[i];
}
}
return max;
}
}

<T extends Comparable>
這樣的話指定擦除到Comparable就停止了,否則的話,擦除到Object,但Object並沒有實現Comparable接口,於是便不能比較了;上界就是規定了擦除的位置;

四、通配符?:
Integer ArrayList
Number ArrayList
Object ArrayList
這些不構成繼承關係,類之間有繼承關係,但他們的泛型類型之間並不構成繼承關係

也有擦除機制,也是擦除到Object
不知道傳入參數類型,通通接收

//寫一個通用的算法:打印集合ArrayList內的所有元素
class GenericAlg3 {
public static void printList1(ArrayList list) {
for (T obj : list) {
System.out.print(obj + " ");
}
System.out.println();
}
//? :通配符 擦除機制 ==== 》Object
public static void printList(ArrayList<?> list) {
for (Object obj : list) {
System.out.print(obj + " ");
}
System.out.println();
}
}
通配符的應用:
因爲基類實現的接口,派生類用的時候沒必要在實現一次。
通配符的上界、下界;
(上界一般用不到,上界主要用來寫入,一般用作庫的開發(如DK源碼))
(下界主要用來讀取)

public static <T extends Comparable<T>> T findMaxVal(ArrayList<? extends T> list) {
    T max = list.get(0);
    for (int i = 0; i < list.size(); i++) {
        if(max.compareTo(list.get(i)) < 0) {
            max = list.get(i);
        }
    }
    return max;
}

/**
 * 通配符的下界:找到是不是有T的基類實現了Comparable接口
 * 主要用來讀取
 */
  public static <T extends Comparable<? super T>> T findMaxVal2(ArrayList<T> list) {
    T max = list.get(0);
    for (int i = 0; i < list.size(); i++) {
        if(max.compareTo(list.get(i)) < 0) {
            max = list.get(i);
        }
    }
    return max;
}

五、注意:
1、泛型數組不能new,可以 this.elem = (T[])new Object[size];不能 new T[]
2、不能new泛型類型的對象 不能 T o = new T();
3、不能new泛型類型的對象數組 (如果能那就寫Object就可以了,然後就又回去了)
4、不能用簡單類型作爲泛型類型的參數,
5、一定要加泛型類型的參數,否則就是Object了,又回去了
6、在靜態方法中,類不能使用泛型類型的參數,因爲靜態方法不依賴於對象,如果不依賴於對象,就不知道這個T是什麼類型,那編譯的時候就沒法(靜態方法中T:會通過實參的類型推演出泛型類型;也可以傳參數的時候添上類型)

class GenericAlg2 {

public static <T extends Comparable<T>> T findMaxVal(T[] array) {
    T max = array[0];
    for (int i = 0; i < array.length; i++) {
        if(array[i].compareTo(max) > 0) {
            max = array[i];
        }
    }
    return max;
}

}

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