摘要:參數化的類型其中是參數化的類型。類型參數的實例或實際類型參數其中是類型參數的實例或實際類型參數。它們并沒有重載,而且泛型中也不存在重載這一說法。除此之外,我們應該盡量地多用泛型方法,而減少對整個類的泛化,因為泛型方法更容易把事情說明白。
泛型是適用于許多許多的類型 ---《JAVA編程思想》
在Java的面向對象編程過程中, 或許你知道運用繼承、接口等一系列面向對象的動作來實現代碼復用,解耦等目的。 但是你知道的,原始類的繼承是單繼承,而接口更是把類型協議寫死了。我們的代碼能否不要這么死板(當然你可以認為那是完美的), 我們的代碼能否適用于更多的不具體的類型?代碼更加通用?甚至這個類型你自己都不知道?,沒錯,在JDK1.5中,JAVA引入了一個新的代碼泛化機制---泛型。
你必須事先知道的一些術語
原始類型
List users=new ArrayList(); 其中List是原始類型。
參數化的類型
Listusers=new ArrayList<>(); 其中List 是參數化的類型。 即把原始類型參數化了。
泛型類型
Listusers=new ArrayList<>(); 其中List 是泛型類型。
類型變量或類型參數
Listusers=new ArrayList<>(); 其中 是類型變量或類型參數。 即一個指向某種類型的變量。 大家知道函數形成參,這里可以看做是"類型形參”。
類型參數的實例或實際類型參數
List泛型也可以如此簡單users=new ArrayList<>(); 其中 是類型參數的實例或實際類型參數。 大家知道函數實參,這里可以看做是"類型實參”。
在JDK1.5版本以前,我們使用List集合get數據是需要轉型的,如下
List users=new ArrayList<>(); users.add("armstrong"); String user = (String) users.get(0);
上面代碼中,List集合是可以傳入任何Object及它的子類的。我們傳入一個String類型的數據,取出來默認是Object,所以你需要轉型。使用原始類型的弊端:在程序運行起來的時候,可能會出現轉型失敗的異常。那么補救方法呢?
Jdk1.5里面是這樣定義List:
public interface Listextends Collection { int size(); boolean isEmpty(); T[] toArray(T[] a); boolean add(E e); ... }
你可以看到List類這個原始類型,定義成了接口List泛型類型。類、接口的泛型定義方式是一樣的,那么我們可以這樣編寫之前那段代碼:
ListusersGenertor=new ArrayList<>(); usersGenertor.add("armstrong"); String userS = usersGenertor.get(0);
而且,此時List
ListusersGenertor=new ArrayList<>(); usersGenertor.add(new Object());// error,此處不能添加Object類型 usersGenertor.add(123);// error,此處不能添加Integer類型 String userS = usersGenertor.get(0);
為了更好的解釋泛型的概念。打個比方,我們知道達爾文的《進化論》中說人和猴子的祖先都是猿。但是人只能生人 猴子只能生猴子,雖然有共同的祖先,但是人類不等于猴類 我們也不能說人是猿。人不等于猿~ 那么List后面跟著一個類型變量T,就是指List只能持有指定類型的元素,如果T如果被String替代,那么List就只能持有String, 而List
List
有同學會說,這個例子太簡單了,能不能來一些有難度的。 其實,我舉這個例子的初衷是讓大家知道---JDK開發人員引入泛型直到現在最大的好處就是為了解決容器轉型的麻煩,而且平時工作中我們用泛型最多的場景是和容器打交道。
非常好用的泛型方法在定義List的接口源碼中我們可以看到如下方法:
T[] toArray(T[] a);
這個方法的作用是把List中的所有元素轉存到另一個指定類型的數組中。List原本裝什么類型的元素,那么數組也裝同樣類型的元素,并且這里傳入的類型和返回值類型一致都是類型變量T[]。
那么泛型方法是如何定義的呢? 在上面代碼中,我們在返回值的前面,用
ListusersGenertor=new ArrayList<>(); usersGenertor.add("zeng"); usersGenertor.add("armstrong"); String[] strings = usersGenertor.toArray(new String[10]); for (String string : strings) { System.out.println("string:_"+string); } List usersGenertor2=new ArrayList<>(); usersGenertor2.add(1); usersGenertor2.add(2); Integer[] ints = usersGenertor2.toArray(new Integer[3] ); for (Integer inta : ints) { System.out.println("Integer:_"+inta); } output: string:_zeng string:_armstrong string:_null string:_null string:_null string:_null string:_null string:_null string:_null string:_null Integer:_1 Integer:_2 Integer:_null
上面的代碼中toArray方法分別傳入了String和Integer兩種不同的引用類型。它們并沒有重載,而且泛型中也不存在重載這一說法。暫時我們可以簡單的想象成String,Integer在編譯期間把T這個類型參數變量替換掉了。
除此之外,我們應該盡量地多用泛型方法,而減少對整個類的泛化,因為泛型方法更容易把事情說明白。
參考資料:
《Java編程思想第四版》
《Effective Java》
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/65641.html
摘要:靜態變量是被泛型類的所有實例所共享的。所以引用能完成泛型類型的檢查。對于這個類型系統,有如下的一些規則相同類型參數的泛型類的關系取決于泛型類自身的繼承體系結構。事實上,泛型類擴展都不合法。 前言 和C++以模板來實現靜多態不同,Java基于運行時支持選擇了泛型,兩者的實現原理大相庭徑。C++可以支持基本類型作為模板參數,Java卻只能接受類作為泛型參數;Java可以在泛型類的方法中取得...
摘要:可以看到,如果我們給泛型類制定了上限,泛型擦除之后就會被替換成類型的上限。相應的,泛型類中定義的方法的類型也是如此。參考語言類型擦除下界通配符和的區別 本篇博客主要介紹了Java類型擦除的定義,詳細的介紹了類型擦除在Java中所出現的場景。 1. 什么是類型擦除 為了讓你們快速的對類型擦除有一個印象,首先舉一個很簡單也很經典的例子。 // 指定泛型為String List list1 ...
摘要:泛型類在類的申明時指定參數,即構成了泛型類。換句話說,泛型類可以看成普通類的工廠。的作用就是指明泛型的具體類型,而類型的變量,可以用來創建泛型類的對象。只有聲明了的方法才是泛型方法,泛型類中的使用了泛型的成員方法并不是泛型方法。 什么是泛型? 泛型是JDK 1.5的一項新特性,它的本質是參數化類型(Parameterized Type)的應用,也就是說所操作的數據類型被指定為一個參數,...
閱讀 2315·2021-09-28 09:45
閱讀 3599·2021-09-24 09:48
閱讀 2266·2021-09-22 15:49
閱讀 3099·2021-09-08 16:10
閱讀 1592·2019-08-30 15:54
閱讀 2327·2019-08-30 15:53
閱讀 3021·2019-08-29 18:42
閱讀 2873·2019-08-29 16:19