2022-10-26
泛型 類型
第七關 泛型的點點滴滴
走到這里,小伙伴基本上把泛型學完了,是不是很有成就感啊,不要著急走開喔,后面還有些細節需要完善。下面我們一起把泛型的細節看一下
1.異常中使用泛型
由于泛型在使用過程會消失, 消失后泛型具體的類型就會用戶Object類型來替代,Object 是沒有 繼承 Exception或者Throwable異常類的, 所以 在定義異常類時,不能使用泛型。
又是因為泛型在使用過程會消失,如果使用泛型來表示異常類型,泛型消失,那么泛型表示的異常就不復存在,就會造成泛型無法捕獲或者處理這種情況。
接下來,小伙們我們一起看如下代碼:
//1.自定義帶泛型的異常類: 不合法,錯誤的寫法。
class MyEx1<T> extends Exception{
public MyEx1(String message) {
super(message);
}
}
//2.定義泛型方法,拋出泛型T: 不合法
public class GenericDemo {
public <T> T doTest( T t){
try {
System.out.println("測試----");
}catch (T t){//錯誤的寫法
throw t;//錯發的寫法
}
return null;
}
}
//3.定義泛型接口(類也可以): 合法,正確的寫法,但不實用(沒有實際用途)。
class GenericTest<E extends Exception>{
void process() throws E;
}
通過代碼演示,我們會發現在異常使用泛型存在諸多問題,我們來歸納總結下:
1.自定義帶泛型的異常類,不合法
由于代碼在運行時,泛型會被擦除,那么T 會被擦拭成Object類,而Object類顯然不會是Throwable的子類,因此它不符合異常的有關規定,所以java編譯器不編譯這種錯誤的寫法。
2.定義泛型方法:拋出泛型T,不合法
其實道理和自定義帶泛型的異常類的一樣,最后T 會被擦拭成Object類,顯然不是異常類,無法捕獲、亦無法拋出
3.定義泛型接口(類也可以),正確的寫法
因為我們定義了泛型的上限,即使運行時,T會被擦除,那么java編譯器依然會把它看成異常,所以不會報錯。
但是這種寫法,還不如定義非泛型接口或者非泛型類,沒有多大實際用途,所以小伙伴知道就可以了。
2.數組與泛型
不能聲明參數化類型的數組, 數組可以記住自己的元素類型,不能用普通方法建立一個泛型數組。
(當然 你如果用反射還是可以創建的,用Array.newInstance。因為在反射時,泛型就消失了)
如下所示:
//定義泛型測試類:
class ArrDemo<T>{
public T[] arr1;//標準寫法,后期運行時不會引發問題
public ArrDemo<Integer>[] arr2;//不標準寫法,后期運行時可能會引發問題
public static void main(String[] args) {
//1.創建對象
ArrDemo<String> ad = new ArrDemo<String>();
//2.操作數組
String[] str_arr1 = ad.arr1;//在創建對象是T指的是String ,arr1就是String類型的數組。
ArrDemo<Integer>[] ad_arr3 = ad.arr2;//ad的泛型是String ,新定義的Integer可能會引發問題
}
}
3.泛型方法
在能夠使用泛型方法的時候,盡量避免使整個類泛化。
如下所示:
public class GenericDemo4 {//1.標準: 推薦的寫法
//1.定義一個泛型方法:
public <E> E test2(E e){
System.out.println("自定義泛型的方法:"+e);
return e;
}
}
4.泛型類型必須是應用類型,不能是基本類
如下所示:
Listlist2 = new ArrayList();//正確的寫法: 引用類型
Listlist2 = new ArrayList();//錯誤的寫法: 基本類型
5.虛擬機中沒有泛型,只有普通類和普通方法
因為泛型在編譯階段我們能看到,可以規范我們開發者使用的類型。
但是泛型在編譯后的class文件,以及最終到 JVM虛擬機中運行,這是泛型被擦除了,所以在虛擬機中只有普通類和普通方法。
闖關練習
請選擇下面描述正確的選項
A: 泛型可以使用基本類型表示
B: 泛型類中必須定義泛型方法
C: 在異常操作中,通常不使用泛型
D: 泛型類型必須是引用類型
答案:C D
第八關 課程總結
這個小節的內容已經學習完了,小伙伴們是不是感覺收獲多多!
剛才我們一起了解了泛型的基本信息和使用,同時完成了幾個闖關小練習,小伙伴現在對泛型的感覺如何呢。
現在,我們一起做個總結吧。
了解泛型是什么 泛型即: "參數化類型",可以把泛型作為"參數", 泛型可以指任意類型,規范java代碼的書寫
了解泛型的優點 泛型可以進行編譯期間進行類型檢查 泛型可以避免類型強轉
掌握泛型的定義和使用
定義泛型接口
定義泛型類
定義泛型方法
在實際開發的場景中能夠使用上面定義的泛型
了解泛型的通配符,以及泛型的上限和下限
泛型的上限,有時又稱之為上邊界,指的是泛型不能超過extends的類型
泛型的下限,有時又稱之為下邊界,指的是泛型得高于super的類型
了解泛型的擦除機制和補償措施
泛型在編譯后的class文件中就消失了。
泛型在使用時應盡量避免new T(),或者使用instanceof, 因為這兩類操作要知道確切的類型。
泛型的補償措施:簡單工廠,工廠方法,模板類,需要小伙們好好學習一下。
了解什么是鉆石操作符
java7之后,規定< > 尖括號就是鉆石操作符,里面的泛型可以省略不寫,還是建議不要省略
相信你已經掌握了大部分的泛型知識點了。對于還沒有理解的知識點。
希望你有時間可以多看看,多敲敲代碼,多多練習。最后希望大家通過這一節泛型的學習,能夠對泛型有一個深入的理解,并且能夠在實際開發中熟練的運用!
開班時間:2021-04-12(深圳)
開班盛況開班時間:2021-05-17(北京)
開班盛況開班時間:2021-03-22(杭州)
開班盛況開班時間:2021-04-26(北京)
開班盛況開班時間:2021-05-10(北京)
開班盛況開班時間:2021-02-22(北京)
開班盛況開班時間:2021-07-12(北京)
預約報名開班時間:2020-09-21(上海)
開班盛況開班時間:2021-07-12(北京)
預約報名開班時間:2019-07-22(北京)
開班盛況Copyright 2011-2023 北京千鋒互聯科技有限公司 .All Right 京ICP備12003911號-5 京公網安備 11010802035720號