1. 程式人生 > >【JavaSE系列-基礎篇6】——有界型別引數

【JavaSE系列-基礎篇6】——有界型別引數

目錄

有界型別引數

可能有時候要限制在引數化型別中可以用作型別引數的型別。舉個例子來說,一個對數字進行操作的方法可能只希望接受Number或其子類的例項。這是有界型別引數。

宣告一個有界型別引數,列出型別引數的名稱,並且跟隨extends關鍵字,後面是它的上限,例如Number。請注意,在這種情況下,擴充套件在一般意義上用於表示“擴充套件”(如在類中)或“實現”(如在介面中)。

public class Box<T> {

    private T t;          

    public void set(T t) {
        this.t = t;
    }

    public
T get() { return t; } public <U extends Number> void inspect(U u){ System.out.println("T: " + t.getClass().getName()); System.out.println("U: " + u.getClass().getName()); } public static void main(String[] args) { Box<Integer> integerBox = new
Box<Integer>(); integerBox.set(new Integer(10)); integerBox.inspect("some text"); // error: this is still String! } }

通過修改我們的泛型方法來包含這個有界型別的引數,將編譯失敗,因為我們呼叫檢查仍然包含一個String:

Box.java:21: <U>inspect(U) in Box<java.lang.Integer> cannot
  be applied to (java.lang.String
) integerBox.inspect("10"); ^ 1 error

除了限制可用於例項化通用型別的型別之外,有界型別引數還允許您呼叫邊界中定義的方法:

public class NaturalNumber<T extends Integer> {

    private T n;

    public NaturalNumber(T n)  { this.n = n; }

    public boolean isEven() {
        return n.intValue() % 2 == 0;
    }

    // ...
}

isEven方法通過n呼叫Integer類中定義的intValue方法。

多重邊界

上述示例說明了使用具有單個繫結的型別引數,但型別引數可以具有多個邊界:

<T extends B1 & B2 & B3>

具有多個邊界的型別變數是繫結中列出的所有型別的子型別。如果一個邊界是一個類,則必須首先指定。例如:

Class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }

class D <T extends A & B & C> { /* ... */ }

如果未先指定繫結A,則會收到編譯時錯誤:

class D <T extends B & A & C> { /* ... */ }  // compile-time error