java中的強(qiáng)迫癥患者

java零基礎(chǔ)入門-高級特性篇(五) 泛型? 上

前面說集合的時候藐唠,有一個往List添加元素的方法add(E e)帆疟,說這個 E 叫泛型,可以表示任何一種類型宇立。為什么往集合添加元素的時候需要泛型踪宠?因為上一章的集合示例過于理想化,人為制造了一個前提妈嘹,就是認(rèn)為往集合里添加元素都是同樣的類型柳琢。但是理想很豐滿,現(xiàn)實很骨感润脸,如果對于一個集合添加的元素沒有約束柬脸,可以隨意往一個集合里面放任何類型的對象,會發(fā)生意想不到的問題毙驯。

為什么有泛型


雙十一你剁手了沒倒堕?每到雙十一,我們唯一的目標(biāo)就是清空購物車爆价,拿起你的手機(jī)垦巴,買買買~好了媳搪,作為一個程序員,這里從代碼的眼光出發(fā)骤宣,看看購物車這個神奇的東西秦爆。

首先有一個集合,就是購物車憔披,用來放商品對象等限。商品的屬性有名稱,價格活逆,類別。然后新建一個商品拗胜,再丟進(jìn)購物車蔗候,我忘了看價格,需要拿出來看看價格埂软,看如何實現(xiàn)锈遥。

購物車

為什么這個關(guān)鍵步驟需要進(jìn)行強(qiáng)制轉(zhuǎn)換類型?你寫上面代碼的時候可以試試不強(qiáng)制轉(zhuǎn)會會發(fā)生什么勘畔。如果不轉(zhuǎn)換所灸,cart.get(0)這個地方拿出的對象是Object類型,無法獲取到price這個屬性的值炫七。不對呀爬立!我放進(jìn)去的明明就是一個商品類型Commodity呀,為什么拿出來的時候變成Object了万哪?不好意思侠驯,購物車不夠智能,并不能記錄每一個你放進(jìn)購物車的東西是什么類型奕巍,他只能通通當(dāng)成Object處理了吟策,因為Object是所有類型的父類,不管你放啥進(jìn)購物車的止,他肯定是個Object檩坚。

這里雖然看個價格很麻煩,還要轉(zhuǎn)換類型诅福,但是終歸能看到類型匾委。但是接下來發(fā)生的情況就不那么簡單了。正當(dāng)我開開心心買買買的時候氓润,突然發(fā)現(xiàn)剩檀,哎喲~不錯喲~居然有的商品還有贈品!真是開心的不得了旺芽。贈品的屬性有名稱沪猴,類別辐啄。看代碼运嗜。

贈品

先看運行結(jié)果是什么壶辜。

Exception in thread "main" java.lang.ClassCastException: com.java.lesson14.Present cannot be cast to com.java.lesson14.Commodity

at com.java.lesson14.Shopping2.main(Shopping2.java:24)

這是啥玩意?不是應(yīng)該輸出兩個價格嗎担租?這個東西叫異常砸民,異常就是程序發(fā)生了錯誤,程序給出的錯誤信息奋救×氩危看看錯誤信息說了啥,ClassCastException尝艘,這個異常叫做類型轉(zhuǎn)換異常演侯。Present cannot be cast to?Commodity,意思是Present類型不能轉(zhuǎn)換成Commodity類型背亥,最后一行是出現(xiàn)錯誤的位置秒际,Shopping2.java:24 ,24行發(fā)生了類型轉(zhuǎn)換錯誤狡汉。

來看看24行發(fā)生了什么娄徊,為什么出現(xiàn)類型轉(zhuǎn)換錯誤。24行將第二個加入到集合的元素轉(zhuǎn)換成Commodity類型盾戴,原來往購物車添加?xùn)|西的時候寄锐,第一個是商品,第二個是贈品,24行將贈品轉(zhuǎn)為商品類型,就發(fā)生了錯誤比被。

為什么寫代碼的時候不報錯呢?運行才報錯呢沿癞?因為我們只設(shè)置了一個購物車,沒有規(guī)定購物車?yán)锩娣攀裁囱矫剩瑳]有規(guī)定當(dāng)然什么都可以放椎扬,扔個贈品進(jìn)去也很正常啊。運行的時候具温,要從購物車?yán)锩鎸|西拿出來蚕涤,上個例子看到,拿出來的時候是不知道這個東西是個什么類型的铣猩,統(tǒng)一認(rèn)為是Object揖铜。完蛋,我不知道哪個要轉(zhuǎn)換成商品類型达皿,哪個要轉(zhuǎn)換成贈品類型天吓,類型轉(zhuǎn)換發(fā)生錯誤可想而知贿肩。

這里使用的是List集合,可以按照順序來判斷類型龄寞,但是換成了Set汰规,那就是真的不知道要轉(zhuǎn)什么類型了。

問題出現(xiàn)了物邑,往集合里面放東西溜哮,拿出來的時候可能會發(fā)生錯誤,集合沒有記錄我扔進(jìn)去元素的類型色解,拿出來又只給我Object茂嗓,這下如何是好?

現(xiàn)在科阎,終于輪到本章主角隆重登場了述吸。

泛型是什么

沒有泛型的時候,集合就是個強(qiáng)迫癥患者萧恕,什么強(qiáng)迫癥刚梭?元素類型不統(tǒng)一就不能清空購物車肠阱,不能清空購物車就渾身難受票唆,心浮氣躁,上躥下跳屹徘。而泛型的出現(xiàn)走趋,恰恰治好了集合的強(qiáng)迫癥。為了能夠清空購物車噪伊,當(dāng)我們新建購物車的時候簿煌,就立下字據(jù),這個購物車只能放商品鉴吹,不是商品通通不讓放姨伟。如何實現(xiàn)?

List cart = new ArrayList();? ?//沒有立字據(jù)豆励,什么都可以放

List<Commodity> cart = new ArrayList<Commodity>();? //立字據(jù)夺荒,只能放Commodity類型的東西進(jìn)購物車

這里的<Commodity>就是泛型。表示這個集合只能放Commodity類型的元素良蒸。你敢放其他類型元素技扼,我就敢報錯。

修改

一旦給集合加上了泛型嫩痰,在編譯的時候剿吻,就會判斷元素類型是否允許加入到集合,就不會出現(xiàn)上面那種只有在運行期才知道類型不對的錯誤了串纺。但是贈品不能添加到購物車怎么辦丽旅?總不能把贈品丟掉吧椰棘,舍不得呀,沒關(guān)系魔招,把贈品變成商品就行晰搀,價格設(shè)置為0。

上面的例子有點小小的問題办斑,但是我不打算改外恕,正好拿來復(fù)習(xí)前面的知識點。一個屬性設(shè)置為常量需要在前面加上static和final這兩個關(guān)鍵字乡翅,并且變量名全部大寫鳞疲。上面例子中這個常量其實是沒有起到作用的,因為在shopping3這個類中蠕蚜,將鉛筆這個贈品強(qiáng)制轉(zhuǎn)換到父類商品尚洽,調(diào)用getPrice()方法是獲取父類中的price屬性,并不是子類贈品里面這個設(shè)置為0的常量靶累。如果要獲取子類價格這個常量0腺毫,需要修改2個地方。第一挣柬,Present類添加getPrice這個方法潮酒,返回常量PRICE。第二邪蛔,Shopping3類強(qiáng)制轉(zhuǎn)換的時候急黎,將第二個元素強(qiáng)制轉(zhuǎn)換為子類Present,這樣打印的時候使用的就是子類PRICE常量侧到。

集合不加泛型是可以的勃教,但是如果元素類型不一致,強(qiáng)迫癥犯了渾身難受匠抗。所以建議使用集合的時候都要加上泛型故源,這樣不僅治好了強(qiáng)迫癥,還能夠使代碼更加健壯汞贸,不會有太多的隱患绳军,不然bug滿天飛小心飯碗不保。

泛型的語法變化

在java5的時候著蛙,有了泛型治好了集合的強(qiáng)迫癥删铃,List,Set踏堡,Map都可以使用泛型來規(guī)范元素的類型猎唁。但是有個缺點就是寫起來太啰嗦了。List和Set還好,Map寫起來真的是手要抽筋诫隅。

Map<String,Object> map = new HashMap<String,Object>();

是不是有個問題腐魂,在定義map的時候就寫了,我這個map元素的key-value類型是:key用String逐纬,value是Object蛔屹,為什么在實現(xiàn)的時候還要再寫一遍?在java7之前豁生,不好意思兔毒,你還真得老老實實寫一遍,但是java7的出現(xiàn)甸箱,可以讓我們偷偷懶了育叁。不需要在實現(xiàn)的時候再寫一遍泛型類型。

Map<String,Object> map = new HashMap<>();

后面只需要一對<>括號即可芍殖,java會根據(jù)前面的定義豪嗽,自己來推斷這里的泛型是什么類型。是不是更先進(jìn)更智能了豌骏。


集合里的泛型是泛型使用最廣泛的地方龟梦,除了治好了集合的強(qiáng)迫癥,泛型還有很多其他的用處窃躲,下期繼續(xù)计贰。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市框舔,隨后出現(xiàn)的幾起案子蹦玫,更是在濱河造成了極大的恐慌赎婚,老刑警劉巖刘绣,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挣输,居然都是意外死亡纬凤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門撩嚼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來停士,“玉大人,你說我怎么就攤上這事完丽×导迹” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵逻族,是天一觀的道長蜻底。 經(jīng)常有香客問我,道長聘鳞,這世上最難降的妖魔是什么薄辅? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任要拂,我火速辦了婚禮,結(jié)果婚禮上站楚,老公的妹妹穿的比我還像新娘脱惰。我一直安慰自己,他們只是感情好窿春,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布拉一。 她就那樣靜靜地躺著,像睡著了一般旧乞。 火紅的嫁衣襯著肌膚如雪舅踪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天良蛮,我揣著相機(jī)與錄音抽碌,去河邊找鬼。 笑死决瞳,一個胖子當(dāng)著我的面吹牛货徙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播皮胡,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼痴颊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了屡贺?” 一聲冷哼從身側(cè)響起蠢棱,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甩栈,沒想到半個月后泻仙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡量没,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年玉转,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殴蹄。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡究抓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出袭灯,到底是詐尸還是另有隱情刺下,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布稽荧,位于F島的核電站橘茉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捺癞,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一夷蚊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧髓介,春花似錦惕鼓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至一膨,卻和暖如春呀邢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背豹绪。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工价淌, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瞒津。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓蝉衣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巷蚪。 傳聞我的和親對象是個殘疾皇子病毡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

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