在 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>