Java泛型約束

無限通配符

通配符類型由問號表示,如 <?> 中所示。對於通用類型,通配符類型爲對象類型用於原始類型。
可以將任何已知類型的泛型分配爲通配符類型。
參考以下示例代碼:

// MyBag  of  String type
MyBag<String> stringMyBag  = new MyBag<String>("Hi");

// You can  assign a  MyBag<String> to  MyBag<?> type
MyBag<?> wildCardMyBag  = stringMyBag;

通配符通配類型中的問號(例如,<?>)表示未知類型。當使用通配符聲明參數化類型作爲參數類型時,這意味着不知道它的類型。

MyBag<?> unknownMyBag = new MyBag<String>("Hello");

上邊界通配符

上邊界通配符表示通配符的上限,如下語法

<? extends T>

這裏,T是一種類型。 <? extends T>表示任何類型爲T或其子類是可接受的。
例如,上限可以是數字類型。

如果傳遞任何其他類型,是Number類型或它的子類,沒有問題。 但是,如果不是Number類型或其子類型的任何東西都會在編譯時被拒絕。

使用上限作爲數字值(Number),可以將方法定義爲 -

class MyBag<T> {
  private T ref;

  public MyBag(T ref) {
    this.ref = ref;
  }

  public T get() {
    return ref;
  }

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

public class Main {
  public static double sum(MyBag<? extends Number> n1,
      MyBag<? extends Number> n2) {
    Number num1 = n1.get();
    Number num2 = n2.get();
    double sum = num1.doubleValue() + num2.doubleValue();
    return sum;
  }

}

不管爲n1n2傳遞的是什麼,它們將始終與Number的賦值兼容,因爲編譯器確保傳遞給sum()方法的參數遵循其聲明中指定的規則 <? extends Number>

下限通配符

指定下限通配符與指定上限通配符相反。使用下限通配符的語法是<? super T>,這表示「任何T的超類型」。

class MyBag<T> {
  private T ref;/*from w  w w. j ava 2  s  .co  m*/

  public MyBag(T ref) {
    this.ref = ref;
  }

  public T get() {
    return ref;
  }

  public void set(T a) {
    this.ref = a;
  }
}
public class Main {
  public static <T> void copy(MyBag<T> source, MyBag<? super T> dest) {
    T value = source.get();
    dest.set(value);
  }
}