3分鐘快速掌握泛型(Generic)

由于本人能力有限毫蚓,文中若有錯(cuò)誤之處扇丛,歡迎指正绿映。
轉(zhuǎn)載請(qǐng)注明出處:http://www.reibang.com/p/75bc58480c11

什么是泛型?

泛型扛芽,即類型參數(shù)化骂蓖。

  1. 泛型是 JDK5 中引入的一種安全機(jī)制。泛型的引入把運(yùn)行時(shí)期易產(chǎn)生的 ClassCastException 轉(zhuǎn)化到編譯時(shí)期川尖。(下面有示例)
  2. Java中的泛型是偽泛型登下,在JVM層并不真正支持泛型。在編譯檢查成功后叮喳,相應(yīng)的class文件中已經(jīng)沒有了泛型的信息被芳。這種機(jī)制叫做 擦除補(bǔ)償 機(jī)制。(下面有示例)
  3. 泛型使用最廣泛的地方是Java集合框架馍悟。
  4. 可以利用泛型的特點(diǎn)筐钟,設(shè)計(jì)出更加靈活的API。
// JDK5之前沒有泛型
List strs1 = new ArrayList();
strs1.add("hello world!");
// 可以添加赋朦,但在使用是可能是產(chǎn)生java.lang.ClassCastException
// strs1.add(123);
String str1 = (String) strs1.get(0);

// JDK6有泛型
List<String> strs2 = new ArrayList<String>();
strs2.add("hello world!");
// strs2.add(123); // 編譯時(shí)期直接報(bào)錯(cuò)
String str2 = strs2.get(0); // 不用強(qiáng)制類型轉(zhuǎn)換
// 通過反射證明偽泛型
List<String> list = new ArrayList<>();
list.add("hello world!");
Method add = list.getClass().getMethod("add", Object.class);
add.invoke(list, 111);
System.out.println(list.get(1)); // java.lang.ClassCastException

泛型類

public class Container<V> {

    private V value;

    public Container(V v) {
        value = v;
    }

    public V getValue() {
        return value;
    }

    public void setValue(V value) {
        this.value = value;
    }
}

泛型接口

public interface Generator<T> {
    public T next();
}

泛型方法

使用原則: 無論何時(shí),只要你能做到李破,你就應(yīng)該盡量使用泛型方法宠哄。也就是說,如果使用泛型方法可以取代將整個(gè)類泛化嗤攻,那么應(yīng)該優(yōu)先采用泛型方法毛嫉。

public class Main {

    public static <T> void outPrint(T t) {
        System.out.println(t);
    }

    public static void main(String[] args) {
        outPrint("findingsea");
        outPrint(123);
        outPrint(true);
    }
}

通配符

使用原則(PECS)
1.如果要從集合中讀取類型T的數(shù)據(jù),并且不能寫入妇菱,可以使用 ? extends 通配符承粤;(Producer Extends)
2.如果要從集合中寫入類型T的數(shù)據(jù)暴区,并且不需要讀取,可以使用 ? super 通配符辛臊;(Consumer Super)
3.如果既要存又要取仙粱,那么就不要使用任何通配符。

  • ?

無邊界通配符彻舰,它的使用形式是一個(gè)單獨(dú)的問號(hào):List<?>伐割,也就是沒有任何限定,不做任何限制刃唤。

  • 上限(<? extends T>)
List<? extends Fruit> flist = new ArrayList<Apple>();
// 編譯錯(cuò)誤隔心,不能添加任何類型
// flist.add(new Apple());
// flist.add(new Fruit());
// flist.add(new Object());
flist.add(null); // null不處于任何類型
// 可以獲取到具體類型
Fruit f = flist.get(0);

flist 的類型是 List<? extends Fruit>,我們可以把它讀作:一個(gè)類型的 List尚胞, 這個(gè)類型可以是繼承了 Fruit 的某種類型硬霍。注意,這并不是說這個(gè) List 可以持有 Fruit 的任意類型笼裳。而是我們不知道這個(gè) List 到底持有什么類型唯卖,所以不能安全的添加一個(gè)對(duì)象。 另一方面侍咱,如果調(diào)用某個(gè)返回 Fruit 的方法耐床,這是安全的。因?yàn)槲覀冎佬ǜ谶@個(gè) List 中撩轰,不管它實(shí)際的類型到底是什么,但肯定能轉(zhuǎn)型為 Fruit昧廷,所以編譯器允許返回 Fruit堪嫂。

  • 下限(<? super T>)
List<? super Apple> apples = new ArrayList<>();
apples.add(new Apple());
apples.add(new RedApple());
// apples.add(new Fruit()); // 編譯錯(cuò)誤

apples 的類型是 List<? super Apple>,它表示某種類型的 List木柬,這個(gè)類型是 Apple 的基類型皆串。也就是說,我們不知道實(shí)際類型是什么眉枕,但是這個(gè)類型肯定是 Apple 的父類型恶复。因此,我們可以知道向這個(gè) List 添加一個(gè) Apple 或者其子類型的對(duì)象是安全的速挑,這些對(duì)象都可以向上轉(zhuǎn)型為 Apple谤牡。但是我們不知道加入 Fruit 對(duì)象是否安全,因?yàn)槟菢訒?huì)使得這個(gè) List 添加跟 Apple 無關(guān)的類型姥宝。

寫在最后

  1. 開發(fā)中翅萤,泛型使用最多的地方就是集合框架。大部分情況下泛型的使用還是比較簡(jiǎn)單的腊满。
  2. 另外套么,泛型的使用多見于一些開源框架中培己。泛型的引入大大增強(qiáng)了API設(shè)計(jì)的靈活性。
  3. 如果你不確定一個(gè)地方能不能使用泛型胚泌,那么請(qǐng)嘗試使用它省咨。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诸迟,隨后出現(xiàn)的幾起案子茸炒,更是在濱河造成了極大的恐慌,老刑警劉巖阵苇,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壁公,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡绅项,警方通過查閱死者的電腦和手機(jī)紊册,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來快耿,“玉大人囊陡,你說我怎么就攤上這事∠坪ィ” “怎么了撞反?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長搪花。 經(jīng)常有香客問我遏片,道長,這世上最難降的妖魔是什么撮竿? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任吮便,我火速辦了婚禮,結(jié)果婚禮上幢踏,老公的妹妹穿的比我還像新娘髓需。我一直安慰自己,他們只是感情好房蝉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布僚匆。 她就那樣靜靜地躺著,像睡著了一般搭幻。 火紅的嫁衣襯著肌膚如雪白热。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天粗卜,我揣著相機(jī)與錄音,去河邊找鬼纳击。 笑死续扔,一個(gè)胖子當(dāng)著我的面吹牛攻臀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纱昧,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼刨啸,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了识脆?” 一聲冷哼從身側(cè)響起设联,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灼捂,沒想到半個(gè)月后离例,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悉稠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年宫蛆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片的猛。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡耀盗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卦尊,到底是詐尸還是另有隱情叛拷,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布岂却,位于F島的核電站忿薇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏淌友。R本人自食惡果不足惜煌恢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望震庭。 院中可真熱鬧瑰抵,春花似錦、人聲如沸器联。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拨拓。三九已至肴颊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渣磷,已是汗流浹背婿着。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人竟宋。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓提完,卻偏偏與公主長得像,于是被迫代替她去往敵國和親丘侠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子徒欣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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

  • 前言 泛型(Generics)的型變是Java中比較難以理解和使用的部分打肝,“神秘”的通配符,讓我看了幾遍《Java...
    珞澤珈群閱讀 7,800評(píng)論 12 51
  • 第8章 泛型 通常情況的類和函數(shù)挪捕,我們只需要使用具體的類型即可:要么是基本類型粗梭,要么是自定義的類。但是在集合類的場(chǎng)...
    光劍書架上的書閱讀 2,145評(píng)論 6 10
  • 2.簡(jiǎn)單泛型 -********Java泛型的核心概念:告訴編譯器想使用什么類型, 然后編譯器幫你處理一切細(xì)節(jié) 2...
    CodingHou閱讀 389評(píng)論 0 0
  • 本文大量參考Thinking in java(解析担神,填充)楼吃。 定義:多態(tài)算是一種泛化機(jī)制,解決了一部分可以應(yīng)用于多...
    谷歌清潔工閱讀 459評(píng)論 0 2
  • 引言 泛型是Java中一個(gè)非常重要的知識(shí)點(diǎn)妄讯,在Java集合類框架中泛型被廣泛應(yīng)用孩锡。本文我們將從零開始來看一下Jav...
    橫沖直撞666閱讀 425評(píng)論 0 0