Java 5 添加了泛型,提供了編譯時類型安全檢測機制,該機制容許程序員在編譯時檢測到非法的類型。
泛型的本質是參數化類型,能夠爲之前處理通用對象的類和方法,指定具體的對象類型。聽起來有點抽象,因此咱們將立刻看一些泛型用在集合上的例子:javascript
先看一個沒有泛型的集合例子:html
List list = new ArrayList(); list.add(new Integer(2)); list.add("a String");
由於 List 能夠添加任何對象,因此從 List 中取出的對象時,由於不肯定(List不記住元素類型)當時候保存進 List 的元素類型,這個對象的類型只能是 Object ,還必須由程序編寫者記住添加元素類型,而後取出時再進行強制類型轉換就,以下:java
Integer integer = (Integer) list.get(0); String string = (String) list.get(1);
一般,咱們只使用帶有單一類型元素的集合,而且不但願其餘類型的對象被添加到集合中,例如,只有 Integer 的 List ,不但願將 String 對象放進集合,而且也不想本身記住元素類型,而且強制類型轉換還可能會出現錯誤。程序員
使用 Generics(泛型)就能夠設置集合的類型,以限制能夠將哪一種對象插入集合中。 這能夠確保集合中的元素,都是同一種已知類型的,所以取出數據的時候就沒必要進行強制類型轉換了,下面是一個 String 類型的 List 的使用例子:數組
List<String> strings = new ArrayList<String>(); strings.add("a String"); String aString = strings.get(0);
以上這個 List
Java 泛型從 Java 7 開始,編譯器能夠自動類型判斷,能夠省略構造器中的泛型,下面是一個Java 7 泛型例子:markdown
List<String> strings = new ArrayList<>();
這也叫作菱形語法(<>), 在上面的示例中,實例化 ArrayList 的時候,編譯器根據前面 List
foreach 循環能夠很好地與泛型集合整合,以下:async
List<String> strings = new ArrayList<>(); // 這裏省略將 String 元素添加進集合的代碼... for(String aString : strings){ System.out.println(aString); }
也可使用泛型迭代器遍歷集合,以下:ide
List<String> list = new ArrayList<String>; Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String aString = iterator.next(); }
注意,泛型類型檢查僅在編譯時存在。在運行時,可使用反射或者其餘方式使字符串集合插入其餘對象,但通常不會這樣作。
固然泛型的用處不只僅限於集合。
從上面的內容中,咱們已瞭解泛型的大概理念。
能夠在自定義 Java 類上使用泛型,並不侷限於 Java API 中的預約義類。定義泛型類只須要在類名後緊跟
public class GenericFactory<T> { Class theClass = null; public GenericFactory(Class theClass) { this.theClass = theClass; } public T createInstance() throws Exception { return (T) this.theClass.newInstance(); } }
其中 Class.newInstance() 方法是反射知識的內容,這裏只要知道此方法用於 theClass 類對象的建立就行。
GenericFactory<MyClass> factory = new GenericFactory<MyClass>(MyClass.class); MyClass myClassInstance = factory.createInstance(); GenericFactory<SomeObject> factory1 = new GenericFactory<SomeObject>(SomeObject.class); SomeObject someObjectInstance = factory1.createInstance();
使用泛型,咱們就沒必要轉換從 factory.createInstance() 方法返回的對象,會自動返回 new GenericFactory
一個泛型方法定義以下:
public static <T> T addAndReturn(T element, Collection<T> collection){ collection.add(element); return element; }
其中 T 是方法返回值,
public T createInstance() throws Exception { ... }
這不是一個泛型方法,而是 GenericFactory
注意在泛型方法中,參數有 2 個,第一個是 T 類型的參數,第二個是元素類型爲 T 的 Collection 集合,編譯器會根據實際參數來推斷 T 爲什麼種類型 ,以下這樣是徹底可行的:
String stringElement = "stringElement"; List<Object> objectList = new ArrayList<Object>(); Object theElement = addAndReturn(stringElement, objectList);
如上,第一個參數爲 String 類型,第二個是 List