優(yōu)雅編程之這樣使用泛型,你就“正橙蠹ィ”了(三十三)

開心一笑

【女:“一天中最幸福的時(shí)刻就是下班后你騎自行車載著我到街角那邊吃鹵肉飯转锈。”
男:“說實(shí)話楚殿〈榭”
女:“你騎自行車載我去吃鹵肉飯±漳В”
男:“說實(shí)話甫煞。”
女:“鹵肉飯……”】

**提出問題******

java開發(fā)中如何更好使用范型???

解決問題

勵(lì)志圖片

以下來自《Effective Java》讀書筆記:

請(qǐng)不要在新代碼中使用原生態(tài)類型

參考高手文章:

http://www.cnblogs.com/nayitian/archive/2013/08/08/3245496.html

http://www.cnblogs.com/TwoWaterLee/p/5878056.html

參數(shù)化類型冠绢,通配符類型和原生態(tài)類型對(duì)比:

  • Set<Object>是個(gè)參數(shù)化類型抚吠,表示可以包含任何對(duì)象的一個(gè)集合;
  • Set<?>則是一個(gè)通配符類型弟胀,表示只能包含某種未知對(duì)象類型的一個(gè)集合楷力;
  • Set則是個(gè)原生態(tài)類型,它脫離了泛型系統(tǒng)孵户。**前兩種是安全的萧朝,最后一種不安全。

無限制通配類型和原生態(tài)類型的區(qū)別是:通配符類型是安全的夏哭,原生態(tài)類型不安全检柬。你可以將任何元素放入到原生態(tài)類型的集合中,但不能將除了null之外的其他任何元素放到Collection<?>中竖配。

例如:

public static void main(String[] args) {
    List<String> strings = new ArrayList<>();
    unsafeAdd(strings, new Integer(42));
    String s = strings.get(0); // Compiler-generated cast
}
//重點(diǎn)在這里何址。list參數(shù)是原生態(tài)類型里逆,整個(gè)編譯過程都不會(huì)出現(xiàn)問題,但是運(yùn)行時(shí)候就是會(huì)報(bào)ClassCastException異常
private static void unsafeAdd(List list, Object o) {
    list.add(o);
}

兩條例外:

  • a.在Class中只能使用原生態(tài)類型用爪,因?yàn)榉盒托畔⒖梢栽谶\(yùn)行時(shí)被擦除原押。
  • b.在操作instanceof時(shí),使用參數(shù)化類型非法偎血。
消除非受檢警告

參考高手文章:
http://blog.csdn.net/lqadam/article/details/52563155

要盡可能地消除每一個(gè)非受檢的警告诸衔。

使用@SuppressWarnings("unchecked")注解,需要注意的是將該注解用在盡可能小的范圍內(nèi)颇玷,能在變量上使用的不在方法上使用笨农,能在方法上使用的不在類上使用。

使用@SuppressWarnings注解時(shí)亚隙,都要添加一條注釋磁餐,說明為什么這么做是類型安全的

列表優(yōu)先于數(shù)組

下面的代碼片段是合法的,卻是不符合預(yù)期:

// 運(yùn)行時(shí)候失敗
Object[] objectArray = new Long[1];
objectArray[0] = “I don’t fit in”; // Throws ArrayStoreException

但下面這段代碼則不合法阿弃,但卻提醒了你怎樣才能達(dá)到預(yù)期:

// Won’t compile!
List<Object> o1 = new ArrayList<Long>(); // Incompatible types
o1.add(“I don’t fit in”);

明顯诊霹,利用列表可以在編譯時(shí)發(fā)現(xiàn)錯(cuò)誤。我們當(dāng)然希望在編譯時(shí)發(fā)現(xiàn)錯(cuò)誤了渣淳。

總結(jié):數(shù)組是協(xié)變的脾还,數(shù)組是具體化的:在運(yùn)行時(shí)才知道并檢查它們的元素類型約束

優(yōu)先考慮泛型入愧,優(yōu)先考慮范型方法

定義泛型方法語(yǔ)法格式如下:

http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html

引用高手的圖片

參考高手文章:

http://www.cnblogs.com/cutter-point/p/5883279.html

修改前:

//這里使用原生類型是不合理的
 public static Set union1(Set s1, Set s2){
    Set result = new HashSet(s1);
    result.addAll(s2);
    return result;
}

修改后:

 //這里的范型沒有安全警告
 public static <E> Set<E> union(Set<E> s1, Set<E> s2){
    Set<E> result = new HashSet<E>(s1);
    result.addAll(s2);
    return result;
}
利用有限制通配符來提升API的靈活性

參考高手文章:

http://www.cnblogs.com/13jhzeng/p/5726511.html

先看下面例子:

修改之前:

public void pushAll(Iterable<E> src) {  
    for (E e : src) {  
        push(e)  
    }  
}  

修改之后:

//src是生成者鄙漏,所以使用extend
public void pushAll(Iterable<? extends E> src) {  
    for (E e : src) {  
        push(e)  
    }      
}      

pushAll的輸入?yún)?shù)類型不應(yīng)該為"E的Iterable接口",而應(yīng)該為"E的某個(gè)子類型的Iterable接口"棺蛛,有一個(gè)通配符類型正符全此意:Iterable<? Extends E>

PECS 表示:producer-extends, consumer-super

如果參數(shù)化類型表示一個(gè)T生產(chǎn)者怔蚌,就使用<? extends T>;如果它表示一個(gè)T消費(fèi)者旁赊,就使用<? super T>桦踊。如果使用得當(dāng),通配符類型對(duì)于類的用戶來說幾乎是無形的终畅。它們使方法能夠接受它們應(yīng)該接受的參數(shù)籍胯,并拒絕那些應(yīng)該拒絕的參數(shù)。如果類的用戶必須考慮通配符類型离福,類的API也許就會(huì)出錯(cuò)杖狼。

假設(shè)添加一個(gè)popAll方法,從堆棧中彈出每個(gè)元素妖爷,添加到指定集合中:

修改前

public void popAll(Collection<E> dst) {
    while(!isEmpty) {
        dst.add(pop());
    }
}

與未修改的putAll一樣蝶涩,應(yīng)當(dāng)允許類型為Number的棧幀放在包括Number在內(nèi)的父類型中。所以,修改為:

修改后

public void popAll(Collection<? super E> dst) {
    while(!isEmpty) {
        //這里dst是消費(fèi)者子寓,所以使用super
        dst.add(pop());
    }
}

總之暗挑,如果參數(shù)化類型表示一個(gè)T生產(chǎn)者,就使用<? extends T>斜友,如果表示一個(gè)T的消費(fèi)者,就使用<? super T>

優(yōu)先考慮類型安全的異構(gòu)容器

參考高手文章:

http://blog.csdn.net/zhang_amao/article/details/52107612

http://blog.csdn.net/tkd03072010/article/details/7722110

public Class Favorites{

    public <T> void putFavorite(Class<T> type, T instance);
    public <T> T getFavorites(Class<T> type);
}

Favorites實(shí)例是類型安全的:當(dāng)你向它請(qǐng)求String的時(shí)候垃它,不會(huì)返回一個(gè)Integer給你鲜屏。同時(shí)它也是異構(gòu)的:不像普通的map,它的所有的鍵都是不同類型的国拇。因此洛史,我們將Favorites稱作類型安全的異構(gòu)容器

Map不能保證鍵和值之間的類型關(guān)系,即不能保證每個(gè)值的類型都與鍵的類型相同酱吝,當(dāng)你考慮到這個(gè)問題時(shí)也殖,可以嘗試使用類型安全的異構(gòu)容器:

public class Favorites {
    private Map<Class<?>, Object> favorites =
            new HashMap<Class<?>, Object>();
    
    public <T> void putFavorites(Class<T> type, T instance) {
        if(type == null)
            throw new NullPointerException();
        favorites.put(type, type.cast(instance));
    }
    
    public <T> T getFavorites(Class<T> type) {
        return type.cast(favorites.get(type));
    }
}

讀書感悟

來自三毛《稻草人手記》

  • 我們還年輕,長(zhǎng)長(zhǎng)的人生可以受一點(diǎn)風(fēng)浪务热。
  • 我喜歡看見幸福的人忆嗜,不管他們結(jié)不結(jié)婚。
  • 快回來吧崎岂!我希望把有生之年都靜靜地跟你分享捆毫。短短的人生我們不要再分開了啊。
  • 肉體的軟弱是一時(shí)的 精神的勝利是永久的
  • 自由是多么可貴的事冲甘,心靈的自由更是我們要牢牢把握住的绩卤;不然,有了愛情仍是不夠的江醇。

其他

如果有帶給你一絲絲小快樂濒憋,就讓快樂繼續(xù)傳遞下去,歡迎轉(zhuǎn)載陶夜,點(diǎn)贊凛驮,頂,歡迎留下寶貴的意見律适,多謝支持辐烂!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市捂贿,隨后出現(xiàn)的幾起案子纠修,更是在濱河造成了極大的恐慌,老刑警劉巖厂僧,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扣草,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辰妙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門鹰祸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人密浑,你說我怎么就攤上這事蛙婴。” “怎么了尔破?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵街图,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我懒构,道長(zhǎng)餐济,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任胆剧,我火速辦了婚禮絮姆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秩霍。我一直安慰自己篙悯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布前域。 她就那樣靜靜地躺著辕近,像睡著了一般。 火紅的嫁衣襯著肌膚如雪匿垄。 梳的紋絲不亂的頭發(fā)上移宅,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音椿疗,去河邊找鬼漏峰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛届榄,可吹牛的內(nèi)容都是我干的浅乔。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼铝条,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼靖苇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起班缰,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤贤壁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后埠忘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脾拆,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馒索,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了名船。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绰上。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖渠驼,靈堂內(nèi)的尸體忽然破棺而出蜈块,到底是詐尸還是另有隱情,我是刑警寧澤渴邦,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布疯趟,位于F島的核電站,受9級(jí)特大地震影響谋梭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜倦青,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一瓮床、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧产镐,春花似錦隘庄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至述雾,卻和暖如春街州,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玻孟。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工唆缴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人黍翎。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓面徽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親匣掸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子趟紊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)碰酝,斷路器霎匈,智...
    卡卡羅2017閱讀 134,711評(píng)論 18 139
  • 前言 人生苦多,快來 Kotlin 砰粹,快速學(xué)習(xí)Kotlin唧躲! 什么是Kotlin造挽? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,218評(píng)論 9 118
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 11,007評(píng)論 6 13
  • 泛型為集合提供了編譯時(shí)類型檢查饭入。 23、不要在代碼中使用原生態(tài)類型 聲明中具有一個(gè)或多個(gè)類型參數(shù)的類或接口統(tǒng)稱為泛...
    Alent閱讀 929評(píng)論 6 2
  • 歲月肛真,給我們定格在信師八九級(jí)美術(shù)班里 那里谐丢,有我們抹不去的共同記憶 同窗共讀播撒下今生的友誼 我們的親情勝似姐妹兄...
    居高不易張閱讀 887評(píng)論 0 2