在 Java 的泛型類型中使用通配符

在 Java 的泛型類型中使用通配符  Java 從版本5起開始引入泛型(generics)機制。咱們知道,Java 的泛型類型如同 java.lang.String,java.io.File 同樣,屬於普通的 Java 類型。比方說,下面兩個變量的類型就是互不相同的:  List<Object> listObj = new ArrayList<Object>();  List<String> listStr = new ArrayList<String>();  雖然 String 是 Object 的子類,可是 List<String> 和 List<Object> 之間並無什麼關係——List<String> 不是 List<Object> 的子類或者子類型。在下面的代碼中,咱們會看到將具備 List<Object> 類型的變量賦給指望 List<Object> 類型參數的方法的話,編譯器在編譯期將會報告一個編譯錯誤。  import java.util.ArrayList;  import java.util.List;  public class GenericsTypeTest {  public static void testMtd(List<Object> l) {      }      public static void main(String[] args) {          List<String> testList = new ArrayList<String>;          // above line will cause a compile error          testMtd(testList);      }  }  若是咱們但願 testMtd 可以接受任意泛型類型的參數,那麼咱們應該使用 ? 通配符來知足這個要求。List<?> 任意類型的對象的數組這麼一個泛型的類型。咱們能夠把以上代碼改爲:  public static void testMtd(List<?> l) {  }  可是這種狀況下,testMtd 的參數能夠接受類型可能對於程序員設計的意圖而言太普遍了一點。由於咱們可能只是但願 testMtd 能夠接受 AbstractList 及其子類的類型的變量,而不接受 AbstractSet 甚至 Random、Locale 等類型的變量。咱們要對通配符有所限制。幸運的是,Java 5 的泛型機制已經考慮到了這一點,咱們可使用邊界通配符(bounded wildcard)形式來知足這個要求。咱們將 testMtd 再修改一下:  Public static void testMtd(List<? Extends AbstractList>) {  }  這樣,List<AbstractList>、List<LinkedList> 等等類型的變量就能夠傳給 testMtd 方法,而儲存其餘類型元素的 List 的泛型類型變量傳給 testMtd 方法將是非法的。除了上邊界通配符(upper bounded wildcard)之外,咱們還可使用下邊界通配符(lower bounded wildcard),例如 List<? super AbstractList>。  最後總結一下使用通配符的泛型類型的三種形式:  GenericType<?>  GenericType<? extends upperBoundType>  GenericType<? super lowerBoundType>
相關文章
相關標籤/搜索