咱們爲何要使用泛型?javascript
在學習集合時,咱們都知道集合中是能夠存聽任意對象的,只要把對象存儲集合後,那麼這時他們都會被提高成Object類型。當咱們在取出每個對象,而且進行相應的操做,這時必須採用向下類型轉換。這個時候就要注意了,很容易出現問題.html
public class GenericDemo { public static void main(String[] args) { Collection coll = new ArrayList(); coll.add("abc"); coll.add("itcast"); coll.add(5);//因爲集合沒有作任何限定,任何類型均可以給其中存放 Iterator it = coll.iterator(); while(it.hasNext()){ //須要打印每一個字符串的長度,就要把迭代出來的對象轉成String類型 String str = (String) it.next(); System.out.println(str.length()); } } }
運行時會出現一下異常.
也就是說咱們雖然能夠向集合中存聽任意類型,可是對他進行相應方法的調用時,必須把他向下轉成之前的類型.java
那麼要咱們顯然來記憶咱們存了什麼類型進去是不靠譜的 ,怎麼來解決這個問題呢?markdown
在JDK5以後,新增了泛型(Generic)語法,咱們能夠指定類或方法支持泛型,這樣咱們對一個集合就只能存進去對應泛型的類型了(這個泛型能夠直接肯定是什麼肯定的類,也能夠預支地使用未知的類型。).而且編譯時期就能夠進行語法檢查.ide
泛型:能夠在類或方法中預支地使用未知的類型。咱們在建立對象時,將未知的類型肯定具體的類型。post
泛型能夠用到類、接口和方法中,分別被稱爲泛型類、泛型接口、泛型方法。學習
1.泛型類ui
//表明泛型的變量能夠隨便定義,通常用 T,K,E... 修飾符 class 類名<表明泛型的變量> { } class ArrayList<E>{ public boolean add(E e){ } public E get(int index){ } .... }
2.含有泛型的方法spa
public class MyGenericMethod { public <T> void show(T t) { System.out.println(t.getClass()); } public <T> T show2(T t) { return t; } }
注意:
2.1.調用方法時,肯定泛型的類型,傳遞的是什麼類型的參數,泛型就是什麼類型
2.2. public 與 返回值中間的<.T>很是重要,能夠理解爲聲明此方法爲泛型方法。只有聲明瞭<.T>的方法纔是泛型方法,泛型類和接口中的使用了泛型的成員方法並非泛型方法.code
3.含有泛型的接口
修飾符 interface接口名<表明泛型的變量> { } public interface MyGenericInterface<E>{ public abstract void add(E e); public abstract E getE(); }
3.1什麼時候肯定泛型的類型呢?
(1)、定義實現類時肯定泛型的類型,此時就會重寫接口中的方法.
public class MyImp1 implements MyGenericInterface<String> { @Override public void add(String e) { // 省略... } @Override public String getE() { return null; } }
(2)、始終不肯定泛型的類型,直到建立對象時,肯定泛型的類型
public class MyImp2<E> implements MyGenericInterface<E> { @Override public void add(E e) { // 省略... } @Override public E getE() { return null; } } public class GenericInterface { public static void main(String[] args) { MyImp2<String> my = new MyImp2<String>(); my.add("aa"); } }
4.泛型的通配符
`
爲何出現呢?
這是由於泛型不存在繼承關係 Collection