如何在 Java 中將泛型(型別引數)限制為特定類的子類?


無論何時想要將型別引數限制為特定類的子型別,都可以使用有界型別引數。如果只將型別(類)指定為有界引數,則當前泛型類只接受該特定類的子型別。

可以透過在尖括號內使用 extends 關鍵字擴充套件所需的類來宣告有界引數,例如:

class Sample <T extends Number>

示例

 線上演示

在下面的 Java 示例中,泛型類 Sample 使用有界引數將型別引數限制為 Number 類的子類。

class Sample <T extends Number>{
   T data;
   Sample(T data){
      this.data = data;
   }
   public void display() {
      System.out.println("Data value is: "+this.data);
   }
}
public class BoundsExample {
   public static void main(String args[]) {
      Sample<Integer> obj1 = new Sample<Integer>(20);
      obj1.display();
      Sample<Double> obj2 = new Sample<Double>(20.22d);
      obj2.display();
      Sample<Float> obj3 = new Sample<Float>(125.332f);
      obj3.display();
   }
}

輸出

Data value is: 20
Data value is: 20.22
Data value is: 125.332

現在,如果將其他型別作為引數傳遞給此類(例如 String),則會生成編譯時錯誤。

示例

 線上演示

public class BoundsExample {
   public static void main(String args[]) {
      Sample<Integer> obj1 = new Sample<Integer>(20);
      obj1.display();
      Sample<Double> obj2 = new Sample<Double>(20.22d);
      obj2.display();
      Sample<String> obj3 = new Sample<String>("Krishna");
      obj3.display();
   }
}

編譯時錯誤

BoundsExample.java:16: error: type argument String is not within bounds of type-variable T
      Sample<String> obj3 = new Sample<String>("Krishna");
            ^
   where T is a type-variable:
      T extends Number declared in class Sample
BoundsExample.java:16: error: type argument String is not within bounds of type-variable T
      Sample<String> obj3 = new Sample<String>("Krishna");
                                       ^
   where T is a type-variable:
      T extends Number declared in class Sample
2 errors

多個邊界

還可以使用 extends 關鍵字列出多個型別作為有界引數,並使用“&”分隔它們,傳遞給此類的(型別)引數應為所有指定類的子型別。

示例

在下面的示例中,我們設定了 Number 和 Comparable 型別的上界,即此類接受同時為這兩個類的子類的型別。

 線上演示

class Sample <T extends Number & Comparable<T> >{
   T data;
   Sample(T data){
      this.data = data;
   }
   public void display() {
      System.out.println("Data value is: "+this.data);
   }
}
public class BoundsExample {
   public static void main(String args[]) {
      Sample<Integer> obj1 = new Sample<Integer>(22);
      obj1.display();
      Sample<Double> obj2 = new Sample<Double>(20.22d);
      obj2.display();
   }
}

輸出

Data value is: 22
Data value is: 20.22

如果將 AtomicInteger 類作為引數傳遞給 Sample 類,由於它不是 Comparable 類的子型別,因此會生成編譯時錯誤。

示例

 線上演示

import java.util.concurrent.atomic.AtomicInteger;
class Sample <T extends Number & Comparable<T> >{
   T data;
   Sample(T data){
      this.data = data;
   }
   public void display() {
      System.out.println("Data value is: "+this.data);
   }
}
public class BoundsExample {
   public static void main(String args[]) {
      Sample<Integer> obj1 = new Sample<Integer>(22);
      obj1.display();
      Sample<Double> obj2 = new Sample<Double>(20.22d);
      obj2.display();
      Sample<AtomicInteger> obj3 = new Sample<AtomicInteger>(124);
      obj3.display();
   }
}

編譯時錯誤

BoundsExample.java:16: error: type argument String is not within bounds of type-variable T
Sample<String> obj3 = new Sample<String>("Krishna");
      ^
   where T is a type-variable:
      T extends Number declared in class Sample
BoundsExample.java:16: error: type argument String is not within bounds of type-variable T
      Sample<String> obj3 = new Sample<String>("Krishna");
                                       ^
   where T is a type-variable:
      T extends Number declared in class Sample
2 errors

更新於: 2019年9月9日

3K+ 次檢視

啟動您的 職業生涯

透過完成課程獲得認證

立即開始
廣告

© . All rights reserved.