泛型是Java SE 1.5的新特性,泛型的本質是參數化類型,也就是說所操做的數據類型被指定爲一個參數。這種參數類型能夠用在類、接口和方法的建立匯中,分別稱爲泛型類、泛型接口、泛型方法。Java語言引入泛型的好處是安全簡單。java
在Java SE 1.5以前,沒有泛型的狀況下,經過對類型Object的引用來實現參數的"任意化","任意化"帶來的缺點是要作顯式的強制類型轉換,而這種轉換是要求開發者對實際參數類型能夠預知的狀況下進行的。對於強制類型轉換錯誤的狀況,編譯器可能不提示錯誤,在運行的時候纔出現異常,這是一個安全隱患。安全
泛型的好處是在編譯的時候檢查類型安全,而且全部的強制轉換都是自動和隱式的,以提升代碼的重用率。app
舉個例子:Box類定義爲一個泛型類:ide
public class Box<T> { private T object; public void set(T object) { this.object = object; } public T get(){ return this.object; } }
建立一個Box對象,不帶泛型參數,發現獲取對象的時候須要強制轉換this
public class Test { public static void main(String[] args){ //建立一個Box對象,不帶泛型參數,發現獲取對象的時候須要強制轉換 Box box = new Box(); box.set(new Apple()); Apple apple = (Apple) box.get(); } }
建立一個Box對象,帶泛型參數,獲取對象的時候就不須要強制轉換code
public class Test { public static void main(String[] args){ //建立一個Box對象,帶泛型參數,獲取對象的時候就不須要強制轉換 Box<Apple> box = new Box<Apple>(); box.set(new Apple()); Apple apple = box.get(); } }
總結下泛型的好處就是 省去了強制轉換,能夠在編譯時候檢查類型安全,能夠用在類,方法,接口上對象
可是咱們定義泛型類,泛型方法,泛型接口的時候常常會遇見不少不一樣的通配符T,E,K,V等等,這些通配符又都是什麼意思呢?繼續往下看接口
這些全都屬於java泛型的通配符,剛開始我看到這麼多通配符,一下暈了,這幾個其實沒什麼區別,只不過是一個約定的代碼,也就是說element
使用大寫字母A,B,C,D....X,Y,Z定義的,就都是泛型,把T換成A也同樣,這裏T只是名字上的意義而已。開發
舉個例子:
public class Test<T> { public List<T> list = new ArrayList<T>(); public static void main(String[] args){ Test<String> test = new Test<String>(); test.list.add("hello"); System.out.println(test.list); } }
和
public class Test<A> { public List<A> list = new ArrayList<A>(); public static void main(String[] args){ Test<String> test = new Test<String>(); test.list.add("hello"); System.out.println(test.list); } }
將T換成了A,在執行效果上是沒有任何區別的,只不過咱們約定好了T表明type,因此仍是按照約定規範來比較好,增長了代碼的可讀性。
若是要定義多個泛型參數,好比說;兩個泛型參數,很典型的一個例子是Map的key,value泛型,咱們也能夠定義一個這樣的
public interface MyMap<K,V> { public K getKey(); public V getValue(); }
public class MyMapImpl<K,V> implements MyMap<K,V> { private K key; private V value; public MyMapImpl(K key,V value){ this.key = key; this.value = value; } @Override public K getKey() { return null; } @Override public V getValue() { return null; } }
這樣就能夠傳入任意類型,建立實例了,不用轉換類型
public class Test{ public static void main(String[] args){ MyMap<String, Integer> mp1= new MyMapImpl<String, Integer>("Even", 8); MyMap<String, String> mp2= new MyMapImpl<String, String>("hello", "world"); MyMap<Integer, Integer> mp3= new MyMapImpl<Integer, Integer>(888, 888); } }
若是要定義超過兩個,三個或者三個以上的泛型參數可使用T1,T2,....Tn,像這樣子
public class Test<T1,T2,T3>{ public static void main(String[] args){ } public void print(T1 t1,T2 t2,T3 t3){ System.out.println(t1.getClass()); System.out.println(t2.getClass()); System.out.println(t3.getClass()); } }
3. 接下來講說List<T>,List<Object>,List<?>區別
泛型三種:
- ArrayList<T> al = new ArrayList<T>();指定集合元素只能是T類型。
T是一種具體的類,例如String,List,Map...等等,這些都是屬於具體的類,這個比較好理解。Class是什麼呢,Class也是一個類,但Class是存放上面String,List,Map...類信息的一個類,有點抽象,咱們一步一步來看。