Java面試重要考點攻克:如何在Java中使用泛型?

全文共2352字,預計學習時長12分鐘

Java面試重要考點攻克:如何在Java中使用泛型?

圖源:unsplash

 

作爲Java中關鍵概念,大多數Java代碼庫都會使用泛型,開發人員在某個時候遇到它們也是不可避免的。正確理解泛型對於掌握Java至關重要,這也會對你的面試有所助益。

 

本文是關於Java中泛型知識的大放送,泛型是什麼,如何在Java中使用,以及它們的優點有哪些,你都能在下文中找到答案。

 

在Java 5中添加泛型是爲了提供編譯時類型檢查,並消除使用集合類時常見的 ClassCastException 風險。Java中的集合類用於存儲和操作對象組。例如,ArrayList集合類可以存儲任何類型的對象。因爲它被設計成Java基類類型對象的容器。

 

因此,ArrayList對象可以保存字符串、整數或任何Java類型。在泛型之前,只創建字符串或整數的ArrayList是不可行的。使用泛型定義ArrayList可以容納的對象類型,因此允許創建單個的ArrayList對象類型:

 

import java.util.ArrayList;
                            publicclassGenEx1{
                                 publicstaticvoidmain(String []args){
                                     ArrayList<String> al =newArrayList<String>();
                                     al.add("Name");
                                     al.add("Age");
                                     al.add(22); // Compile Error!
                                 }
                            }

如上例,泛型類型是通過使用尖括號定義的。在本例中,只有String對象可以存儲在ArrayList中。Java中的集合類現在具有泛型類型。接下來,讓我們來看看如何編寫自己的泛型類、接口和方法。

 

Java面試重要考點攻克:如何在Java中使用泛型?

 

泛型類

 

在泛型類聲明中,類的名稱後面是類型參數部分。可以使用相同的語法來創建通用接口。類型參數,也稱爲類型變量,是用於指定泛型類型名稱的標識符。泛型類的類型參數部分可以包括一個或多個用逗號分隔的類型參數,這些類也稱爲參數化類。

 

classTest<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;
              }
                     }
          publicclassGenEx2{
               publicstaticvoidmain(String []args){
                   Test<String,Integer> pair1 =newTest<String,Integer>("ID",223);
                   Test<String,Integer> pair2 =newTest<String,Integer>("Age",22);
                   System.out.println(pair1.getKey() +"="+ pair1.getValue() );
                   System.out.println(pair2.getKey() +"="+ pair2.getValue() );
               }
          }

在上例中,測試類有兩個名爲K和 v的類型參數,因此測試類的對象可以存儲兩種不同類型的值。

 

Java面試重要考點攻克:如何在Java中使用泛型?

 

泛型方法

 

如果可以編寫一個排序方法來對整數數組、字符串數組或任何支持排序的類型的數組中的元素進行排序,該有多好?

 

Java面試重要考點攻克:如何在Java中使用泛型?

圖源:unsplash

 

Java泛型方法允許用一個方法聲明指定一組相關類型。這樣能夠編寫單個泛型方法聲明,該聲明可以用不同類型的參數調用。類型參數部分必須在方法返回類型之前指定,類型參數也可以用作方法的返回類型。

 

publicclassGenEx3{
                          publicstatic< E >voidprintArray( E[] inputArray ) {
                    for(E element : inputArray) {
                        System.out.print(element +" ");
                    }
                    System.out.println();
               }
                publicstaticvoidmain(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 方法可以用來打印任何類型數組的元素。

 

Java面試重要考點攻克:如何在Java中使用泛型?

 

泛型中的有界類型參數

 

到目前爲止,我們只看到了無界泛型類型參數。無界意味着泛型類型參數可以是我們想要的任何類型,有時可能需要限制允許傳遞給類型參數的類型。例如,對數字進行操作的方法可能只想接受Number類或其子類的實例,爲此使用了有界類型參數。

 

若要聲明有界類型參數,要列出類型參數的名稱,後跟extends關鍵字,然後是它的上界。

 

 

publicabstractclassCage<T extendsAnimal> {
               abstractvoidaddAnimal(T animal)
           }
           classAnimal{}
           classDogextendsAnimal{}
           classCatextendsAnimal{}

 

在本例中,Cage類的泛型類型必須始終是Animal或Animal類的一個子類。因此,我們可以將Cat、Dog或Animal類作爲泛型類型參數傳遞。如果需要,還可以爲泛型類型聲明多個界限。上面示例中的抽象類可以按照如下所示進行修改:

 

public abstract class Cage<T extends Animal& Comparable<T>>

 

在這裏,類型參數現在必須同時考慮Animal類和Comparable接口。

 

Java面試重要考點攻克:如何在Java中使用泛型?

 

泛型中的通配符和子類型

 

問號(?)是泛型中的通配符,表示未知類型。如果希望泛型方法處理所有類型,在本例中可以使用無界通配符。無界通配符由<?>表示,還可以使用綁定通配符。有界通配符有兩種類型,上界通配符和下界通配符。

 

Java面試重要考點攻克:如何在Java中使用泛型?

圖源:unsplash

 

上界通配符用於放寬對方法中變量類型的限制。例如,假設不知道list是數字、整數還是Double類型。那麼如何得到列表中所有元素的和呢?可以使用上界通配符來解決這個問題:

 

publicvoid method( List<? extends Number> list){
                       double sum =0;
                       for(Number i : list){
                        sum += i.doubleValue();
                       }
                       System.out.println(sum);
                     }

 

下界通配符用於增加對方法中變量類型的限制。假設只想向一個列表中添加整數,同時又想接受一個Integer超類型的列表。可以使用一個下界通配符來實現這一點:

 

publicvoid 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 =newArrayList<>();
                     ArrayList<? extends Number> numList = intList; // OK
           ArrayList<Integer> intList2 =newArrayList<>();
                     ArrayList<Number> numList2 = intList2; // Compile Error!

 

diamond操作符,也稱爲diamond語法,是作爲Java 7中的一個新特性引入的。diamond操作符的目的是在創建對象時簡化泛型的使用。

 

ArrayList<String> al = newArrayList<>();

 

通過使用diamond操作符,可以簡化字符串ArrayList的聲明。

 

Java面試重要考點攻克:如何在Java中使用泛型?

 

泛型的好處

 

講過如何使用泛型之後,讓我們來探討一下,我們爲何要使用泛型呢?使用泛型有三個主要原因:

 

· 類型安全

· 不需要類型轉換

· 可重用代碼

 

泛型確保了編譯時的安全性,這允許在編譯代碼時捕獲無效類型。因此,不需要擔心運行時異常。不需要單獨的類型轉換是使用泛型的另一個優點。定義初始類型,然後讓代碼進行轉換。

 

Java面試重要考點攻克:如何在Java中使用泛型?

圖源:unsplash

 

還可以避免代碼重複。如果沒有泛型,必須針對不同的類型複製和粘貼相同的代碼。使用泛型可以不需要這樣做。

 

好啦,關於Java中泛型的知識都在這裏了,要好好掌握呀!

 

Java面試重要考點攻克:如何在Java中使用泛型?

一起分享AI學習與發展的乾貨
歡迎關注全平臺AI垂類自媒體 “讀芯術”

(添加小編微信:dxsxbb,加入讀者圈,一起討論最新鮮的人工智能科技哦~)

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