什麼是泛型?
泛型,即“引數化型別”。例如:定義方法時有形參,然後呼叫此方法時傳遞實參。引數化型別就是將型別由原來的具體的型別引數化,類似於方法中的變數引數,此時型別也定義成引數形式(可以稱之為型別形參),然後在使用/呼叫時傳入具體的型別(型別實參)。
使用泛型有什麼好處?(官方介紹)
1.型別安全。 泛型的主要目標是提高 Java 程式的型別安全。通過知道使用泛型定義的變數的型別限制,編譯器可以在一個高得多的程度上驗證型別假設。沒有泛型,這些假設就只存在於程式設計師的頭腦中(或者如果幸運的話,還存在於程式碼註釋中)。
2.消除強制型別轉換。 泛型的一個附帶好處是,消除原始碼中的許多強制型別轉換。這使得程式碼更加可讀,並且減少了出錯機會。
3.潛在的效能收益。 泛型為較大的優化帶來可能。在泛型的初始實現中,編譯器將強制型別轉換(沒有泛型的話,程式設計師會指定這些強制型別轉換)插入生成的位元組碼中。但是更多型別資訊可用於編譯器這一事實,為未來版本的 JVM 的優化帶來可能。由於泛型的實現方式,支援泛型(幾乎)不需要 JVM 或類檔案更改。所有工作都在編譯器中完成,編譯器生成類似於沒有泛型(和強制型別轉換)時所寫的程式碼,只是更能確保型別安全而已。
泛型的使用有哪些規則和限制?
1、泛型的型別引數只能是類型別(包括自定義類),不能是簡單型別。
2、同一種泛型可以對應多個版本(因為引數型別是不確定的),不同版本的泛型類例項是不相容的。
3、泛型的型別引數可以有多個。
4、泛型的引數型別可以使用extends語句,例如。習慣上成為“有界型別”。
5、泛型的引數型別還可以是萬用字元型別。例如Class<?> classType = Class.forName(Java.lang.String);
泛型使用場景:
底層框架API封裝,方法的形參以及返回值引數。
泛型類和介面
以List為例:
假設我們有三個類Animal、Dog、Cat,它們 的關係Dog extends Animal、Cat extends Animal
對比結論:
1與2比較:當泛型類或介面指定型別,型別實參只能是指定類或其子類
1與3比較:當泛型類或介面不指定具體型別時,型別實參為Object。
泛型方法
語法:泛型宣告必須在方法的修飾符(public,static,final,abstract等)之後,返回值宣告之前;可以宣告多個泛型,用逗號隔開。
萬用字元(上界、下界、無界)
上界
簡介:
上界萬用字元中的上界,指的是泛型內的型別,最高是Animal類,最低不限,只要是繼承了Animal類,都可以通過編譯,這也就是為什麼叫 "上界",最高型別就是Animal類。
分析:
因為“? extends Animal”可代表Animal或其子類,上面的操作應該是可行的。事實上是”不行“,即無法通過編譯。為什麼呢?
在List list裡只能新增Animal類物件及其子類物件(如Dog和Cat物件),在List裡只能新增Dog類和其子類物件,不能新增Animal物件(不是Dog的子類)。
這裡的List<? extends Animal>資料型別不定,如果傳入的是List,這三個add操作是OK的,但是傳入的是List或List會引發型別不相容問題;Java為了保護其型別的一致性,不能往list新增任意物件的,不過卻可以新增null。
下界
簡介:
下界萬用字元中的下界,指的是泛型內的型別,最低是Animal類,最高到超類Object,只要是Animal的父類,都可以通過編譯,這也就是為什麼叫 "下界",因為最低是Animal類。
分析 :
既然最低是Animal類,為什麼animals.add(dog)和animals.add(cat)不報錯呢?
Java多型,任何一個子類都可向上轉型到父類。
無界
簡介
“?”可以代表任意型別,也就是未知型別
萬用字元使用總結
上界萬用字元<? extends T> 指的是,引用內的泛型範圍,最高是T類,最低不限
可以取元素
不能新增元素
下界萬用字元<? super T> 指的是,引用內的泛型範圍,最低是T類,最高是超類Object
可以取元素,但是取出的元素是Object
可以新增元素,新增的元素,必須是T類或者其子類
以上屬於原創文章,轉載請註明作者@怪咖
QQ:208275451