如何在Java中使用泛型 -Manusha
泛型是Java中的關鍵概念。大多數Java程式碼庫都將使用它們。因此,不可避免的是某個時候開發人員會遇到它們。這就是為什麼正確理解它們至關重要。正確理解泛型也將幫助您獲得Java面試機會。
在本文中,我將討論泛型是什麼,如何在Java中使用它們以及它們的優點。
Java 5中新增了泛型,以提供編譯時型別檢查,並消除了使用集合類時常見的ClassCastException風險。
Java中的集合類用於儲存和操作物件組。例如,ArrayList集合類可以儲存任何型別的物件。因為它被設計為Java基類型別Object的容器。因此,ArrayList物件可以容納String或Integer或任何Java型別。使用泛型,我們可以定義ArrayList可以容納的物件型別。因此允許建立單個物件型別ArrayLists。
public class GenEx1{ public static void main(String []args){ ArrayList<String> al = new ArrayList<String>(); al.add("Name"); al.add("Age"); al.add(22); // Compile Error! } } |
如您在上面的示例中看到的那樣,泛型型別是透過使用尖括號來定義的。在此示例中,只能將String物件儲存在ArrayList中。Java中的集合類現在具有通用型別。現在讓我們看看如何編寫我們自己的通用類,介面和方法。
泛型類
在泛型類宣告中,類的名稱後跟型別引數部分。我們可以遵循相同的語法來建立泛型介面。型別引數也被稱為型別變數,是用於指定一個泛型的型別名稱的識別符號。泛型類的型別引數部分可以包含一個或多個用逗號分隔的型別引數。這些類也稱為引數化類。
class Test<K, V>{ private K key; private V value; Test(K key, V value){ this.key = key; this.value = value; } public K getKey(){ return key; } public V getValue(){ return value; } } public class GenEx2{ public static void main(String []args){ Test<String,Integer> pair1 = new Test<String,Integer>("ID",223); Test<String,Integer> pair2 = new Test<String,Integer>("Age",22); System.out.println(pair1.getKey() + "=" + pair1.getValue() ); System.out.println(pair2.getKey() + "=" + pair2.getValue() ); } } |
在上面的示例中,Test類具有兩個名為K和V的型別引數。因此,Test類的物件可以儲存兩種不同型別的值。
泛型方法
如果我們可以編寫一個單一的排序方法來對Integer陣列,String陣列或任何支援排序的型別的陣列中的元素進行排序,那會很好,對嗎?Java泛型方法允許我們使用單個方法宣告來指定一組相關型別。您將能夠編寫一個可以用不同型別的引數呼叫的通用方法宣告。必須在方法返回型別之前指定型別引數部分。型別引數也可以用作方法的返回型別。
public class GenEx3{ public static < E > void printArray( E[] inputArray ) { for(E element : inputArray) { System.out.print(element +" "); } System.out.println(); } public static void main(String args[]){ Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 }; Character[] charArray = { 'P', 'I', 'Z', 'Z', 'A' }; System.out.print("integerArray contains: "); printArray(intArray); System.out.print("doubleArray contains: "); printArray(doubleArray); System.out.print("characterArray contains: "); printArray(charArray); } } |
在上面的示例中,printArray方法可用於列印任何型別的陣列的元素。
泛型中的有界型別引數
到目前為止,我們只看到了無界限的泛型型別引數。無界意味著我們的泛型型別引數可以是我們想要的任何型別。有時您可能希望限制允許傳遞給引數的型別。例如,對數字進行操作的方法可能只希望接受Number類或其子類的例項。有界型別引數用於此目的。要宣告一個有界的型別引數,請列出該型別引數的名稱,然後是extends關鍵字,然後是其上限。
public abstract class Cage<T extends Animal> { abstract void addAnimal(T animal) } class Animal{} class Dog extends Animal{} class Cat extends Animal{} |
在示例中,籠型的通用型別必須始終是Animal或Animal類的子類。因此,我們可以將Cat,Dog或Animal類作為通用型別引數傳遞。
如果需要,我們還可以為泛型型別宣告多個範圍。因此,可以修改以下示例中的抽象類,如下所示。
public abstract class Cage<T extends Animal & Comparable<T>> |
在這裡,型別引數現在必須同時考慮Animal類和Comparable介面。
泛型中的萬用字元和子型別
問號(?)是泛型中的萬用字元,表示未知型別。如果我們希望我們的通用方法適用於所有型別,在這種情況下,可以使用無界萬用字元。無界萬用字元由<?>表示。我們還可以使用有界萬用字元,有界萬用字元有兩種型別:上界萬用字元和下界萬用字元。
上界萬用字元用於在方法中放寬對變數型別的限制。例如,假設我們不知道列表將是數字,整數還是雙精度型別。那麼我們如何獲得該列表中元素的總和?我們可以使用上限萬用字元來解決此問題。下面的示例顯示瞭如何實現它。
public void method( List<? extends Number> list){ double sum = 0; for(Number i : list){ sum += i.doubleValue(); } System.out.println(sum); } |
下界萬用字元用於增加方法中對變數型別的限制。假設我們只想將Integers新增到列表中,而我們也想接受Integer的超型別列表。我們可以使用下界萬用字元來實現此目的。從下面的示例中,我們可以看到如何使用它。
public void addIntegers(List<? super Integer> list){ list.add(new Integer(10)); list.add(new Integer(20)); } |
雖然Integer在Java中是一個亞型Number,List<Integer>是不是一個亞型List<Number>?他們的共同父母是List<?>。因此,泛型類中的子型別使用萬用字元完成。下面的示例將幫助您理解這一點。
ArrayList<? extends Integer> intList = new ArrayList<>(); ArrayList<? extends Number> numList = intList; // OK ArrayList<Integer> intList2 = new ArrayList<>(); ArrayList<Number> numList2 = intList2; // Compile Error! |
泛型的優勢
既然您知道如何使用泛型,那麼您必須考慮為什麼我們需要使用它們。嗯,我們使用它們的三個主要原因是:
- 型別安全
- 不需要型別轉換
- 可重用程式碼
泛型確保了編譯時的安全性,這使您可以在編譯程式碼時捕獲無效型別。因此,您無需擔心執行時異常。不需要泛型轉換是使用泛型的另一個優點。您定義初始型別,然後讓程式碼為您進行轉換。我們還可以避免程式碼重複。沒有泛型,我們必須複製並貼上相同的程式碼,但要使用不同的型別。使用泛型,我們不必這樣做。
相關文章
- 如何在Java中使用同步 -ManushaJava
- Java中的泛型Java泛型
- Java中泛型的詳細解析,深入分析泛型的使用方式Java泛型
- Java泛型理解與使用Java泛型
- 【java】【泛型】泛型geneticJava泛型
- Java中的泛型方法Java泛型
- java靜態方法使用泛型Java泛型
- 深入解析Java中的泛型Java泛型
- Java中如何使用泛型實現介面中的列表集合?Java泛型
- Java泛型Java泛型
- JAVA API:ArrayList(泛型類)基本使用JavaAPI泛型
- Java中建立泛型型別的例項Java泛型型別
- Java 泛型中易混淆的地方Java泛型
- Java 泛型中的萬用字元Java泛型字元
- Java 中的泛型方法及 FunctionJava泛型Function
- Java 泛型原理Java泛型
- java泛型一二Java泛型
- Java(7)泛型Java泛型
- Java-泛型Java泛型
- Java+泛型Java泛型
- 重學Java之泛型的基本使用Java泛型
- Java不可不知的泛型使用Java泛型
- Java 中的泛型 集合(List,Set) MapJava泛型
- HarmonyOS 專案中泛型的使用泛型
- Java™ 教程(泛型原始型別)Java泛型型別
- 淺談java泛型Java泛型
- java 基礎 泛型Java泛型
- Java泛型複習Java泛型
- 認識Java泛型Java泛型
- Java泛型筆記Java泛型筆記
- JAVA泛型入門Java泛型
- Java 泛型詳解Java泛型
- Java基礎-泛型Java泛型
- Java:Collection集合、泛型Java泛型
- Java泛型知識Java泛型
- Java基礎 —— 泛型Java泛型
- Java™ 教程(泛型萬用字元使用指南)Java泛型字元
- python使用泛型Python泛型