金華哪里做網(wǎng)站怎么做百度推廣平臺(tái)
一、前言
? 是不是平時(shí)寫業(yè)務(wù)代碼的時(shí)候很少用到這個(gè)寫法:Map<? extends String, ?>,這是Map類型,Map的鍵是? extends String 類型,值是?。為什么不是我們平時(shí)寫的Map< String, Object>,這種寫法有什么好處,然后為什么能夠這樣寫。
二、泛型擴(kuò)展
我們分析Map<? extends String, ?>,首先我們理解為什么能這樣寫。
根據(jù)Map<類型,類型> 我們可以推出只要這兩個(gè)位置<類型,類型> 放入的是類型就可以。
那么這里的?是指通配類。但是為什么不是用個(gè)?就行,還用?? extends String。我們知道一個(gè)類繼承一個(gè)類 還是一個(gè)類。所以整個(gè)?? extends String 也是一個(gè)類型,這是合理的。
那么我們是不是可以擴(kuò)展?Map<? extends String, ?>
public Map<? extends String,?> getStr() {Map<? extends String,?> m = new HashMap<String,String>();return m;}
比如我們可以定義一個(gè)類?
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T>
這又是什么意思呢
分解一下?M extends BaseMapper<T> 這是個(gè)類型
ServiceImpl<M extends BaseMapper<T>, T> 這是類型
最后這是個(gè)類型
ServiceImpl<M extends BaseMapper<T>, T> implements IService<T>
這里嵌套了3個(gè)類型
組成一個(gè)了類型
那這里為啥一下子用M 一下子用T代碼類型呢
三、java泛型
如果定義的一個(gè)類或接口有一個(gè)或多個(gè)類型變量,則可以使用泛型。泛型類型變量由尖括號(hào)界定,放在類或接口名的后面,下面定義尖括號(hào)中的T稱為類型變量。意味著一個(gè)變量將被一個(gè)類型替代替代類型變量的值將被當(dāng)作參數(shù)或返回類型。對于List接口來說,當(dāng)一個(gè)實(shí)例被創(chuàng)建以后,T將被當(dāng)作一個(gè)函數(shù)的參數(shù)下面分別是泛型類、泛型接口的定義:
public class Gen<T>{/泛型類……}public interface List<T> extends Collection<T>{//泛型接口
……
}
要定義泛型方法,只需將泛型參數(shù)列表置于返回值前。
public class ExampleA{public<> voidf(Tx){System.out.println(x.getClass().get Name());}publiec static void main(String args[ ]){ExampleA ea= new ExampleA();ea-f("");ea.f(10);ea.f(a);ea.f(ea);}
}
四、泛型的優(yōu)點(diǎn)
Java語言中引入泛型是一個(gè)較大的功能增強(qiáng)。不僅語言、類型系統(tǒng)和編譯器有了較大的變化,以支持泛型,而且類庫也進(jìn)行了很大的改動(dòng),許多重要的類,比如集合框架,都已經(jīng)成為泛型化的了。這帶來了很多好處:
1、類型安全
泛型的主要目標(biāo)是提高Java程序的類型安全。通過知道使用泛型定義的變量的類型限制,編譯器可以在非常高的層次上驗(yàn)證類型假設(shè)。沒有泛型,這些假設(shè)就只存在于系統(tǒng)開發(fā)人員的頭腦中。
通過在變量聲明中捕獲這一附加的類型信息,泛型允許編譯器實(shí)施這些附加的類型約束。類型錯(cuò)誤就可以在編譯時(shí)被捕獲了,而不是在運(yùn)行時(shí)當(dāng)作ClassCastException展示出來。將類型檢查從運(yùn)行時(shí)挪到編譯時(shí)有助于Java開發(fā)人員更早、更容易地找到錯(cuò)誤,并可提高程序的可靠性。
2、消除強(qiáng)制類型轉(zhuǎn)換
泛型的一個(gè)附帶好處是,消除源代碼中的許多強(qiáng)制類型轉(zhuǎn)換。這使得代碼更加可讀,并且減少了出錯(cuò)機(jī)會(huì)。盡管減少強(qiáng)制類型轉(zhuǎn)換可以提高使用泛型類的代碼的累贊程度,但是聲明泛型變量時(shí)卻會(huì)帶來相應(yīng)的累贊程度。在簡單的程序中使用一次泛型變量不會(huì)降低代碼累贊程度。但是對于多次使用泛型變量的大型程序來說,則可以累積起來降低累贊程度。所以泛型消除了強(qiáng)制類型轉(zhuǎn)換之后,會(huì)使得代碼加清晰和筒潔。
3、更高的運(yùn)行效率
在非泛型編程中,將筒單類型作為Object傳遞時(shí)會(huì)引起B(yǎng)oxing(裝箱)和Unboxing(拆箱)操作,這兩個(gè)過程都是具有很大開銷的。引入泛型后,就不必進(jìn)行Boxing和Unboxing操作了,所以運(yùn)行效率相對較高,特別在對集合操作非常頻繁的系統(tǒng)中,這個(gè)特點(diǎn)帶來的性能提升更加明顯。
4、潛在的性能收益
泛型為較大的優(yōu)化帶來可能。在泛型的初始實(shí)現(xiàn)中,編譯器將強(qiáng)制類型轉(zhuǎn)換(沒有泛型的話,Java系統(tǒng)開發(fā)人員會(huì)指定這些強(qiáng)制類型轉(zhuǎn)換)插入生成的字節(jié)碼中。但是更多類型信息可用于編譯器這一事實(shí),為未來版本的JVM的優(yōu)化帶來可能。
五、使用泛型注意事項(xiàng)
①在定義一個(gè)泛型類時(shí),在“<>”之間定義形式類型參數(shù),例如:“class TestGen<K,V>”,其中“K”,“V”不代表值,而是表示類型。
②實(shí)例化泛型對象時(shí),一定要在類名后面指定類型參數(shù)的值(類型),一共要有兩次書寫。
③泛型中<Kextends ObjecD,extends>并不代表繼承,它是類型范圍限制。
④使用泛型時(shí),泛型類型必須為引用數(shù)據(jù)類型,不能為基本數(shù)據(jù)類型,Java中的普通方法,構(gòu)造方法,靜態(tài)方法中都可以使用泛型,方法使用泛型之前必須先對泛型進(jìn)行聲明,可以使用任意字母,一般都要大寫。
⑤不可以用一個(gè)本地類型(如int float)來替換泛型。
⑥運(yùn)行時(shí)類型檢查,不同類型的泛型類是等價(jià)的(Pair與Pair是屬于同一個(gè)類型Pair),這一點(diǎn)要特別注意,即如果obj instance of Pai == true的話,并不代表objget First()的返回值是一個(gè)String類型。
⑦泛型類不可以繼承Exception類,即泛型類不可以作為異常被拋出。
⑧不可以定義泛型數(shù)組。
⑨不可以用泛型構(gòu)造對象,即:first = new T();是錯(cuò)誤的。
⑩在static方法中不可以使用泛型,泛型變量也不可以用static關(guān)鍵字來修飾
?不要在泛型類中定義equals(Tx)這類方法,因?yàn)镺bject類中也有equals方法,當(dāng)泛型類被擦除后,這兩個(gè)方法會(huì)沖突。
?根據(jù)同一個(gè)泛型類衍生出來的多個(gè)類之間沒有任何關(guān)系,不可以互相賦值。
?若某個(gè)泛型類還有同名的非泛型類,不要混合使用,堅(jiān)持使用泛型類。