Java泛型集合與泛型類


泛型的本質是什么

什么是泛型,泛型是一種模板技術,就好比排序,所有的排序策略,核心問題是比較和交換,如果一種算法對double有效,則只要提供比較大小的規則,該算法也對String甚至任意數據類型有效,而泛型可以使得這樣的排序算法一個實現就應用到多中情形。

結合這種概念,就有了泛型集合,好比ArrayList集合的實現,無論對於什么數據類型,其算法結構都是一樣的,於是從JDK5后有了泛型集合。

泛型有什么好處

當然,有了泛型集合和泛型技術后,泛型帶來的好處就不只是代碼重用了,還包括類型安全,以及更好的可讀性。要知道下面的代碼,在編寫代碼的時候是不會報錯的,要命的是在運行的時候就會:

1 List list1 = new ArrayList();// 非泛型集合
2 list1.add("testString");
3 list1.add(Integer.valueOf(10));
4 for (Object s : list1) {
5     Integer num = (Integer) s;
6     // 類型不安全,會拋出異常
7 }

但是如果是泛型集合,你在編寫代碼的時候JDK就直接告訴你這里不可以這么使用了:

List<String> list2 = new ArrayList<String>();
//list2.add(1);//類型檢查,不是允許的類型無法放入集合

這就是所謂的類型安全了。這是泛型的第二個好處。

當然泛型的另外一個好處就是增強可讀性,取出數據的時候不再有完全沒有意義的強制類型轉換,因為程序員應該知道這個類型是什么。

 

泛型的非協變性

Java中的泛型集合不是協變的,下面的代碼你覺得可以編譯通過嗎:

List<String> list3 = new ArrayList<String>();
List<Object> list4 = list3;

看起來沒什么問題對吧,一個是Object集合,一個是String集合,完全兼容啊,事實上是不行的,如果行的話,泛型集合ArrayList的實例就可以裝入任何對象了不是嗎?

這里還有個小知識:Java的泛型支持是編譯期技術,所謂的類型擦除就是這個意思,我們后面再詳細聊。

那么這個問題怎么解決呢?需求是肯定存在的呀,比如我們有個方法定義:

public static void printElements(List<Object> objs)

這個方法希望接受任何List集合,顯然通過上面的內容,我們知道傳參數是傳不進去的。

解決的辦法很簡單,講List<Object> 換成List<?>,這個問號就是泛型語法中的任何類型的意思,上面的代碼換成這樣的語法,就可以接受任何類型了:

//方法聲明
public static void printElements(List<?> objs) 
//方法調用
List<String> list5 = new ArrayList<String>();
printElements(list5);

 

當然,?是沒有任何約束,我們也可以對接受的類型進一步約束,比如下面的方法定義:

public static void printElements(List<? extends Parent> objs)

 

這樣我們的方法要求集合的元素必須是Parent類的子類,比如Number可以限制為數字,別問我怎么知道Number的 (#^.^#)

當然,很多同學還見過這種的:

public static void printElements(List<? super Parent> objs)

反之,這樣限制了參數必須是List集合且集合的元素必須是Parent類的父類。(這是super在Java中的第三種用法,你知道還有哪兩種嗎?)

 

下次我給大家分享泛型類,靜態泛型方法,有興趣的關注我的博客喲。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM