一、泛型的簡單使用
? ??1昼捍、泛型怎么使用
????在編寫代碼的過程中识虚,有的時候,使用泛型類妒茬,但有時候忘了(偷懶)沒有指定其泛型担锤,很多時候其實并不會報錯,但在運行調(diào)用指定方法的時候乍钻,就會出問題肛循。泛型能夠提高自身代碼的清晰度铭腕,在后期維護代碼,他人調(diào)用接口的時候多糠,就能方便的識別出泛型類的參數(shù)累舷。類型變量使用大寫形式,且比較短夹孔, 這是很常見的被盈。在 Java 庫中, 使用變量 E 表示集合的元素類型搭伤, K 和 V 分別表示表的關(guān)鍵字與值的類型只怎。T ( 需要時還可以用臨近的字母 U 和 S ) 表示“ 任意類型”。
? ? 2闷畸、泛型的類型限制
? ??不能確定泛型對象含有相應(yīng)的方法尝盼,因此可以通過extends對其進行限定,規(guī)定其只能實現(xiàn)了Demo2方法佑菩,這里extends不是繼承的extends盾沫,只是限定的意思,T可以是Demo2的子類殿漠,也可以是實現(xiàn)類赴精,還有Demo2本身限定可以有多個,但只能有一個類(多個接口)绞幌,但類必須放在第一位蕾哟。
二、泛型知識進階
????1莲蜘、泛型和虛擬機
? ? 在虛擬機中沒有相應(yīng)的泛型對象谭确,虛擬機中只有普通的類,所有的類都會進行泛型類型擦除票渠,轉(zhuǎn)化成普通類逐哈。
? ? 2、泛型類型擦除
? ??原始類型的名字就是刪去類型參數(shù)后的泛型類型名问顷。擦除( erased) 類型變量 , 并替換為限定類型 (無限定的變量用 Object) 昂秃,如圖:
? ??原始類型用第一個限定的類型變量來替換,如圖
? ? 但是杜窄,有時候你會遇到這樣的問題肠骆,如圖
? ?在本例中,在子類DateInterval有函數(shù)void setSecond(LocalDate second)方法塞耕,父類Pair中擦除了泛型后蚀腿,有函數(shù)void setSecond(Object second)方法,這兩個方法不是同一個方法扫外,不會覆蓋唯咬,因此纱注,按照常理來說,在DateInterval也會繼承參數(shù)為Object的方法胆胰,這樣就會有一個問題狞贱,在多態(tài)的情況下如下代碼
DateInterval interval= new DateInterval();
Pair<LocalDate> pair=interval;
pair.setSecond(aDate);
????在Pair中不存在setSecond(LocalDate second)方法蜀涨,因此只能調(diào)用Object參數(shù)的方法瞎嬉,但Object的方法沒有被重寫過,就只能調(diào)用Pair中的Object方法厚柳,這樣泛型和多態(tài)就沖突了氧枣,為了解決這個沖突,編譯器會在DateInterval類中生成橋方法public void setSecond(Object second){setSecond(setSecond((Date) second)}該方法覆蓋了父類的方法别垮,在調(diào)用的時候便监,會調(diào)用該方法調(diào)用了LocalDate方法,這樣邏輯就走通了
泛型無法實例化類型變量
public Pair() { first = new T(); second = new T(); }//無法使用
應(yīng)該要這樣使用,如圖碳想,在Pair創(chuàng)建一個構(gòu)造器表達式烧董。
????在這里使用了Supplier是函數(shù)式接口,有一個get函數(shù)胧奔,其返回泛型參數(shù)T逊移。makePair方法中調(diào)用了Pair的有參構(gòu)造器,實現(xiàn)了泛型的(實例化)龙填。還有一點胳泉,在靜態(tài)方法中,無法使用類的泛型參數(shù)岩遗,要使用需要自定義泛型參數(shù)扇商。