JAVA 基礎知識點複習(十五)泛型

定義

在編譯時期就對元素的類型進行檢查,一旦發現不匹配就編譯失敗。在編譯時泛型就被擦除了,所以無法在運行時得知其類型參數的類型。通過泛型可以定義類型安全的數據結構(類型安全),而無須使用實際的數據類型(可擴展),這能夠顯著提高性能並得到更高質量的代碼(高性能),因爲可以重用數據處理算法,而無須複製類型特定的代碼(可重用)。

泛型可以定義在類,接口,方法上

  • 定義時尖括號裏的每個元素都代指一種未知類型
  • 尖括號的位置非常講究,必須在類名之後或者方法返回值之前
  • 泛型在定義處只具備Object方法的能力
  • 基本數據類型不能作爲泛型參數
// 泛型接口
public interface Genericity<T> {
    T test();
}

public class Son implements Genericity<Integer> {
    @Override
    public Integer test() {
        return null;
    }
}

// 泛型類 在編譯時是無法知道K和V具體是什麼類型,只有在運行時纔會真正根據類型來構造和分配內存。
@Data
public class Container<K, V> {

    private K key;

    private V value;

    public Container(K key, V value) {
        this.key = key;
        this.value = value;
    }

    // 這裏不能用static修飾 靜態方法無法訪問類上定義的泛型。
    public K test(V v){
        return null;
    }
	// String不等於java.lang.String,只是一個自定義的泛型類型
    public static <String> String test2(String str){
        return str;
    }


    public static void main(String[] args) {
        // 這裏如果傳入的是Integer類型,編譯不會報錯,運行會報ClassCastException
        Container<String, String> container = new Container(1, 2);
        System.out.println(container.getKey());
        System.out.println(container.getValue());
    }
}

泛型的限定

<? extends E> 泛型上限 接收E或者E的子類,一般在存儲元素時使用上限,取值時用E來接收,不會存在類型安全問題

public static void printCollection(List<? extends Number> list){
        Number number = list.get(0);
    }

<? super E> 泛型下限 接收E或者E的父類,從集合取值時可以用E或者E的父類接收

public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

泛型擦除

List<String> list = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
System.out.println(list.getClass() == list2.getClass()); // true

泛型擦除帶來的問題

  • 不能使用泛型來重載方法
  • 2.不能catch同一個異常的不同泛型實例
  • 3.不同泛型類的靜態變量是共享的
  • 4.泛型間不存在繼承關係,不能使用List 來接收List類型的參數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章