1.什么是泛型?
泛型:把類型明確的工作推遲到**創(chuàng)建對象或調(diào)用方法**的時候才去明確的特殊的類型
Java泛型設(shè)計原則:只要在**編譯時期**沒有出現(xiàn)警告,那么運行時期就不會出現(xiàn)ClassCastException異常.
2.為什么需要泛型?
早期Java是使用Object來代表任意類型的,但是向下轉(zhuǎn)型有強轉(zhuǎn)的問題,這樣程序就不太安全。
首先,我們來試想一下:沒有泛型,集合會怎么樣
- Collection、Map集合對元素的類型是沒有任何限制的。本來我的Collection集合裝載的是全部的Dog對象,
但是外邊把Cat對象存儲到集合中,是沒有任何語法錯誤的。
- 把對象扔進集合中,集合是不知道元素的類型是什么的,僅僅知道是Object。因此在get()的時候,返回的是Object。外邊獲取該對象,還需要強制轉(zhuǎn)換
有了泛型以后:
- 代碼更加簡潔【不用強制轉(zhuǎn)換】
- 程序更加健壯【只要編譯時期沒有警告,那么運行時期就不會出現(xiàn)ClassCastException異?!?- 可讀性和穩(wěn)定性【在編寫集合的時候,就限定了類型】
3.泛型類、接口
泛型類就是把泛型定義在類上,用戶使用該類的時候,才把類型明確下來
class 類名稱 <泛型標識,泛型標識,...> {
private 泛型標識 變量名;
... ...
}
常用泛型標識:T、E、K、V
泛型類注意事項:
- 泛型類,如果沒有指定具體的數(shù)據(jù)類型,此時,操作類型是Object
- 泛型的類型參數(shù)只能是類類型,不能是基本數(shù)據(jù)類型
- 泛型類型在邏輯是可以看成是多個不同的類型,但實際上都是相同的類型
從泛型類派生子類
- 子類也是泛型類,子類和父類的泛型類型要一致
class CHildGeneric<T> extends Generic<T>
- 子類不是泛型類,父類要明確泛型的數(shù)據(jù)類型
class ChildGeneric extends Generic<String>
泛型接口
interface 接口名稱 <泛型標識,泛型標識,...>{
泛型標識 方法名;
... ...
}
泛型接口的使用
- 實現(xiàn)類不是泛型類,接口要明確數(shù)據(jù)類型
- 實現(xiàn)類是泛型類,實現(xiàn)類和接口的泛型類要一致
4.泛型方法
修飾符 <T,E,...> 返回類型 方法名(形參列表){
方法體...
}
泛型方法與可變參數(shù)--...代表可變參數(shù),可以接受數(shù)組
public static <E> void print(E... e){
for (int i=0;i<e.length;i++){
System.out.print(e[i])
}
}
泛型方法總結(jié):
- 泛型方法能使方法獨立于類而產(chǎn)生變化
- 如果static方法要使用泛型能力,就必須使其成為泛型方法
public static <T,E,K> void printType(T t,E e,K k){
System.put.println(t + "\t" + t.getClass().getSimpleName());
}
5.泛型通配符
什么是類型通配符?
- 類型通配符一般是“?”代替具體的類型實參
- 類型通配符是類型實參,不是類型形參
類型通配符上限
類/接口 <? extends 實參類型>
要求該泛型的類型,只能是實參類型,或者實參類型的子類;
類型通配符下限
類/接口 <? super 實參類型>
要求該泛型的類型,只能是實參類型,或者實參類型的父類;
6.泛型擦除
泛型是java 1.5才引入的概念。
泛型信息只存在于代碼編譯階段,在進入JVM之前,與泛型相關(guān)的信息會被擦除掉,我們稱之為類型擦除。
image.png
image.png
image.png
7.泛型和數(shù)組
泛型數(shù)組的創(chuàng)建
- 可以聲明帶泛型的數(shù)組引用,但是不能直接創(chuàng)建帶泛型的數(shù)組對象
- 可以通過java.long.reflect.Array的newInstance(Class <T> ,int)創(chuàng)建T[]數(shù)組
8.泛型和反射
反射常用的泛型類
- Class<T>
- Constructor<T>
反射實現(xiàn)的3中方式:
第一種:通過Object類的getClass方法
Class cla = foo.getClass();
第二種:通過對象實例方法獲取對象
Class cla = foo.class;
第三種:通過Class.forName方式
Class cla = Class.forName("xx.xx.Foo");
對應(yīng)視屏教程:
https://www.bilibili.com/video/BV1xJ411n77R?p=13
參考:https://segmentfault.com/a/1190000014120746#item-4-5
https://blog.csdn.net/wfk2975019671/article/details/90604294