泛型的意義:
泛型用來保證類型的統一,主要目的之一就是用來指定容器要持有什麼類型的對象,而且由編譯器來保證類型的正確性。
1.類型安全,通過設置泛型,可以讓編譯器驗證類型
2.消除強制轉換。如果不用泛型,將元素從容器中取出時,都是由object類型向目標類型強制轉換。而由於泛型的擦除,所有的泛型類型變量都會被替換爲原始類型,在獲取的時候,集合會實現變量的強制轉換,轉換是隱式的。
- 泛型類:public class Test<T>
- 泛型接口:public interface Generator<T> {T next()}
泛型可以用於接口,例如生成器Generator,是一種專門負責創建對象的類。 - 泛型方法:public <T> void test(T x)
是否擁有泛型方法,與這個類是否泛型沒有關係。
類型變量限定:
<T extends myClass>
<T super myClass>
***通配符:<?>
泛型的擦除:
當你在使用泛型時,任何具體的類型信息都被擦除了。編譯器在編譯的時候去掉類型信息,生成不包含類型信息的java字節碼。
泛型類型參數有限定的將擦除到它的第一個邊界,無限定的變量會擦除到object。
泛型的侷限:
- 基本類型無法作爲類型參數,但是java具備自動基本類型包裝功能。原因是類型擦除後,原始類型變爲object,而object不能存儲int等基礎類型的值。
- 由於擦除,一個類不能實現同一個泛型接口的兩種變體。
- 不能創建參數化類型的數組。如Pair<String>[] table = new Pair<String>[10];是錯誤的,因爲擦除會將string信息抹去,所以只要是Pair類型的對象都可以被加入。
- 使用帶有泛型類型參數的轉型或instanceof不會有任何效果,也不能實例化類型變量。用反射調用class.newInstance()解決
- 在靜態方法和靜態變量中不能使用泛型。因爲泛型中泛型參數的實例化是在定義對象時指定,而靜態方法和變量可以不需要對象就可以調用。