1. 程式人生 > 其它 >泛型介紹、泛型集合與非泛型集合的比較、類-介面-方法的引數化、為什麼要使用泛型、如何學習泛型

泛型介紹、泛型集合與非泛型集合的比較、類-介面-方法的引數化、為什麼要使用泛型、如何學習泛型

技術標籤:Java_泛型集合

非泛型集合的潛在問題

泛型以及Lambda表示式可能是Java程式語言最重要的改進之一。

泛型是Java程式語言的功能,允許程式設計師編寫引數化的程式碼。
最初建立它們是為了解決集合的某些問題。 因此,術語“泛型集合”現在通常一起使用。

要了解泛型,讓我們看看它如何解決集合問題。

考慮以下程式碼,該程式碼使用沒有泛型的List集合:

        List listNames = new ArrayList();
        listNames.add("Tom");
        listNames.add("Mary"
); listNames.add("Peter");

此列表listNames應該儲存String物件。 以下語句獲取此列表中的第二個元素:

String name = (String) listNames.get(1);

在此,需要強制轉換為String,因為get()方法返回Object型別的物件。

到現在為止還挺好。 假設在程式的某些地方,您可能錯誤地將String以外的物件新增為列表中的第二個元素:

        Date startDate=new Date();
        listNames.add(startDate);

這段程式碼仍然合法,因為add()方法可以接受任何型別的物件。 現在,下面這條語句將出現問題:

        String name2 = (String) listNames.get(3);
        System.out.println(name2);

此分配期望在右側使用String物件,但是返回的實際物件是Date物件。 編譯器無法在編譯時檢測到此問題,因為在該語句在執行時執行之前,一切似乎都很好,將丟擲ClassCastException:

非泛型集合的風險從上面的案例可以觀察到

應用泛型的集合

可以使用如下泛型來重寫以上程式碼段:
        List<String> listNames=new ArrayList<>();
        listNames.
add("Tom"); listNames.add("Mary"); listNames.add("Peter");

列表listNames使用String型別進行引數化,從現在開始,如果您錯誤地將非String物件新增到此集合中,則編譯器將發出錯誤。 例如:

在這裡插入圖片描述

泛型程式碼是安全的,因為它可以確保新增到集合中的所有元素都是引數化型別。 否則會發生編譯錯誤。
使用泛型,編譯器可以在編譯時檢測違規情況,從而消除了潛在的錯誤。
從泛型集合中獲取元素時,我們無需強制轉換物件

String name = listNames.get(1);

這是安全的,因為泛型確保集合不會儲存錯誤的物件型別。

泛型解決了普通集合潛在的不安全問題

泛型不僅使程式碼更安全,而且更具可讀性

類、介面、方法的引數化

另外,泛型允許您編寫泛型程式碼。 這意味著您可以編寫引數化的介面,類和方法。

第一個例子,我們不必走太遠,只需看看Java Collections Framework中使用的List 介面:

public interface List<E> extends Collection<E> {
 
    boolean add(E e);
     
    E get(int index);
     
}

在這裡,類List的引數型別為E-表示元素。 通過引數化,我們可以在建立集合時指定具體型別,如上述示例所示。

請注意,Java Collections Framework中的所有介面和類都像這樣被引數化,例如 Set ,Queue ,Map <K,V>,ArrayList ,HashSet 等

現在,讓我們看一下如何使用泛型對方法進行引數化。 以Collections實用程式類的sort()方法為例:

public static <T> void sort(List<T> list, Comparator<? super T> c) {
    // code goes here...
}

Don’t worry if you don’ t understand this code right now. Just to know that you can write parameterized methods like that, for the sake of readability, safety and reusability.

為什麼要使用泛型?

  1. 如您在上面的示例中所看到的,泛型保證沒有向集合中新增任何錯誤的型別。 更強大的型別檢查使程式碼更具可讀性
  2. 如您在上面的示例中所見,從集合中取出元素時,我們不必使用強制轉換,這使程式碼更簡單易讀
  3. 實現泛型通用演算法

乍一看,泛型似乎易於使用(如您在上面的示例中所看到的),但是如果更深入地瞭解萬用字元,有界型別,型別擦除等概念,泛型將變得更加複雜且難以理解。

後續學習建議

oracle官方文件
還建議您檢視Java Collections Framework的Java原始檔。 介面和類,如Iterable,Collection,List,ArrayList,Map,HashMap等,以瞭解如何編寫通用程式碼。