什么是泛型
參數(shù)化的類型:將需要傳入的屬性,進(jìn)行參數(shù)化,實(shí)際調(diào)用時(shí)才指定傳入的數(shù)據(jù)類型。
為什么要用泛型
- 同樣的一段代碼
邏輯相同,只是傳入的參數(shù)不同,如果不使用泛型就需要進(jìn)行很多方法的重寫。 - 運(yùn)行時(shí)產(chǎn)生類型轉(zhuǎn)換異常。
如List list = new ArrayList();
list.add("a");
list.add(1);
取的時(shí)候需要強(qiáng)制類型轉(zhuǎn)換,會(huì)產(chǎn)生錯(cuò)誤。
使用泛型的好處
實(shí)現(xiàn)傳入不同的參數(shù),來執(zhí)行相同的代碼。嚴(yán)格要求傳入的參數(shù)類型,不需要強(qiáng)制類型轉(zhuǎn)換,編譯期間就可以發(fā)現(xiàn)錯(cuò)誤。
泛型種類
-
泛型類
定義泛型類:只需在類名后面加尖括號即可,尖括號中的字母可隨意設(shè)置。
public class Demo<T>{
private T data;
public T getData(){
return data;
}
public void setData(T data){
this.data = data;
}
}
public static void main(String[]args){
Demo<String>demo = new Demo<>();
demo.setData("test");
}
-
泛型方法
定義泛型方法:修飾符和返回值類型中間要有<參數(shù)類型>,泛型方法可定義在任意位置。
注意 定義在泛型類中的泛型方法,傳入的參數(shù)類型可以與泛型類傳入的類型不同,泛型類傳入的類型只影響普通方法。
public <T> T demo(T t){
return t;
}
調(diào)用的兩種方式:
1.<String>demo("a");
2.demo("a");
-
泛型接口
定義泛型接口:與泛型類類似只需在方法名后面加尖括號即可,尖括號中的字母可隨意設(shè)置。
public interface Demo<T>{
public T demo();
}
泛型接口的兩種實(shí)現(xiàn)方式:
第一種
public class ImpDemo<T>implements Demo<T>{
@Override
public T demo(){
return null;
}
}
第二種
public class ImpDemo<T>implements Demo<String>{
@Override
public String demo(){
return null;
}
}
類型變量的限定
注意T extends 可繼承一個(gè)類和多個(gè)接口通過&來間隔,但只能繼承一個(gè)類,并且需寫在第一個(gè)。
因?yàn)閖ava語法規(guī)定單繼承多實(shí)現(xiàn)且必須類放在第一個(gè)。
泛型類和方法通用。
public static <T extends Comparable>T min(T a, T b){
if(a.compareTo(b)>0){
return a;
}else{
return b;
}
}
泛型的缺點(diǎn)
- 約束和局限性
①不能實(shí)例化類型變量
②靜態(tài)域或方法里不能引用類型變量因?yàn)閟tatic關(guān)鍵字是在實(shí)例化之前進(jìn)行處理的,所以編譯器不能確定要生成何種類型
靜態(tài)方法本身是泛型方法可以
public class Demo<T>{
private T data;
public Demo{
//①
this.data = new T();
}
}
③泛型不支持基本數(shù)據(jù)類型但支持他們的包裝類因?yàn)榉盒托枰獙ο箢愋?/code>
④不支持類型判定即不支持instanceof,因?yàn)榫幾g時(shí)會(huì)對泛型進(jìn)行擦除。
⑤可以定義泛型數(shù)組,但不能創(chuàng)建泛型數(shù)組。
⑥泛型類不能繼承異常e xtend Exception,也不能捕獲泛型異常
有一種寫法可以
public <T extend Throwable> void doSomeThing(T t) throws T{
try{}catch(Throwable e){
throw t;
}
}
類型的繼承規(guī)則
泛型沒有任何繼承關(guān)系但泛型類可以繼承或擴(kuò)展其他泛型類,如List和ArrayList
通配符類型
- 用來解決泛型沒有任何繼承關(guān)系的問題
①定義通配符:<? extend 類>
?代表子類或類本身。
注意只能使用在方法上不能在類上用,且類代表了上界,即?不能傳入類的父類。
不支持set且只能get上界本身
用于安全的訪問數(shù)據(jù)
②定義通配符:<? super 類>
?代表類或類的父類。
注意只能使用在方法上不能在類上用,且類代表了下界,即?不能傳入類的子類。
支持set類本身和類的子類,不能set類的父類
用于安全的寫入數(shù)據(jù)
虛擬機(jī)是如何實(shí)現(xiàn)泛型
類型擦除,變成了Object,如果泛型有extends 則取extends的第一個(gè)用來作為擦除類型,偽泛型jdk編譯時(shí)會(huì)自動(dòng)做類型轉(zhuǎn)換。
到這了泛型就全部記錄在這里了,如果你覺得對你有幫助,可以點(diǎn)贊關(guān)注,這個(gè)系列會(huì)持續(xù)進(jìn)行更新的。
最后送一句話給自己也與各位共勉