java泛型立倍、泛型的基本介紹和使用

現(xiàn)在開始深入學(xué)習(xí)java的泛型了灭红,以前一直只是在集合中簡單的使用泛型,根本就不明白泛型的原理和作用口注。泛型在java中变擒,是一個十分重要的特性,所以要好好的研究下寝志。
一娇斑、泛型的基本概念
泛型的定義:泛型是JDK 1.5的一項新特性,它的本質(zhì)是參數(shù)化類型(Parameterized Type)的應(yīng)用材部,也就是說所操作的數(shù)據(jù)類型被指定為一個參數(shù)毫缆,在用到的時候在指定具體的類型。這種參數(shù)類型可以用在類乐导、接口和方法的創(chuàng)建中苦丁,分別稱為泛型類、泛型接口和泛型方法物臂。
泛型思想早在C++語言的模板(Templates)中就開始生根發(fā)芽芬骄,在Java語言處于還沒有出現(xiàn)泛型的版本時,只能通過Object是所有類型的父類和類型強制轉(zhuǎn)換兩個特點的配合來實現(xiàn)類型泛化鹦聪。例如在哈希表的存取中,JDK 1.5之前使用HashMap的get()方法蒂秘,返回值就是一個Object對象泽本,由于Java語言里面所有的類型都繼承于java.lang.Object,那Object轉(zhuǎn)型為任何對象成都是有可能的姻僧。但是也因為有無限的可能性规丽,就只有程序員和運行期的虛擬機(jī)才知道這個Object到底是個什么類型的對象。在編譯期間撇贺,編譯器無法檢查這個Object的強制轉(zhuǎn)型是否成功赌莺,如果僅僅依賴程序員去保障這項操作的正確性,許多ClassCastException的風(fēng)險就會被轉(zhuǎn)嫁到程序運行期之中松嘶。
泛型技術(shù)在C#和Java之中的使用方式看似相同艘狭,但實現(xiàn)上卻有著根本性的分歧,C#里面泛型無論在程序源碼中翠订、編譯后的IL中(Intermediate Language巢音,中間語言,這時候泛型是一個占位符)或是運行期的CLR中都是切實存在的尽超,List<int>與List<String>就是兩個不同的類型官撼,它們在系統(tǒng)運行期生成,有自己的虛方法表和類型數(shù)據(jù)似谁,這種實現(xiàn)稱為類型膨脹傲绣,基于這種方法實現(xiàn)的泛型被稱為真實泛型掠哥。
Java語言中的泛型則不一樣,它只在程序源碼中存在秃诵,在編譯后的字節(jié)碼文件中续搀,就已經(jīng)被替換為原來的原始類型(Raw Type,也稱為裸類型)了顷链,并且在相應(yīng)的地方插入了強制轉(zhuǎn)型代碼目代,因此對于運行期的Java語言來說,ArrayList<int>與ArrayList<String>就是同一個類嗤练。所以說泛型技術(shù)實際上是Java語言的一顆語法糖榛了,Java語言中的泛型實現(xiàn)方法稱為類型擦除,基于這種方法實現(xiàn)的泛型被稱為偽泛型煞抬。(類型擦除在后面在學(xué)習(xí))
使用泛型機(jī)制編寫的程序代碼要比那些雜亂的使用Object變量霜大,然后再進(jìn)行強制類型轉(zhuǎn)換的代碼具有更好的安全性和可讀性。泛型對于集合類來說尤其有用革答。
泛型程序設(shè)計(Generic Programming)意味著編寫的代碼可以被很多不同類型的對象所重用战坤。

實例分析:
在JDK1.5之前,Java泛型程序設(shè)計是用繼承來實現(xiàn)的残拐。因為Object類是所用類的基類途茫,所以只需要維持一個Object類型的引用即可。就比如ArrayList只維護(hù)一個Object引用的數(shù)組:
public class ArrayList//JDK1.5之前的
{
public Object get(int i){......}
public void add(Object o){......}
......
private Object[] elementData;
}
這樣會有兩個問題:
1溪食、沒有錯誤檢查囊卜,可以向數(shù)組列表中添加類的對象
2、在取元素的時候错沃,需要進(jìn)行強制類型轉(zhuǎn)換
這樣栅组,很容易發(fā)生錯誤,比如:
/*jdk1.5之前的寫法枢析,容易出問題/
ArrayList arrayList1=new ArrayList();
arrayList1.add(1);
arrayList1.add(1L);
arrayList1.add("asa");
int i=(Integer) arrayList1.get(1);//因為不知道取出來的值的類型玉掸,類型轉(zhuǎn)換的時候容易出錯
這里的第一個元素是一個長整型,而你以為是整形醒叁,所以在強轉(zhuǎn)的時候發(fā)生了錯誤司浪。

所以。在JDK1.5之后辐益,加入了泛型來解決類似的問題断傲。例如在ArrayList中使用泛型:
/** jdk1.5之后加入泛型*/
ArrayList<String> arrayList2=new ArrayList<String>(); //限定數(shù)組列表中的類型
// arrayList2.add(1); //因為限定了類型,所以不能添加整形
// arrayList2.add(1L);//因為限定了類型智政,所以不能添加整長形
arrayList2.add("asa");//只能添加字符串
String str=arrayList2.get(0);//因為知道取出來的值的類型认罩,所以不需要進(jìn)行強制類型轉(zhuǎn)換

還要明白的是,泛型特性是向前兼容的续捂。盡管 JDK 5.0 的標(biāo)準(zhǔn)類庫中的許多類垦垂,比如集合框架宦搬,都已經(jīng)泛型化了,但是使用集合類(比如 HashMap 和 ArrayList)的現(xiàn)有代碼可以繼續(xù)不加修改地在 JDK 1.5 中工作劫拗。當(dāng)然间校,沒有利用泛型的現(xiàn)有代碼將不會贏得泛型的類型安全的好處。

在學(xué)習(xí)泛型之前页慷,簡單介紹下泛型的一些基本術(shù)語憔足,以ArrayList<E>和ArrayList<Integer>做簡要介紹:
整個成為ArrayList<E>泛型類型
ArrayList<E>中的 E稱為類型變量或者類型參數(shù)
整個ArrayList<Integer> 稱為參數(shù)化的類型
ArrayList<Integer>中的integer稱為類型參數(shù)的實例或者實際類型參數(shù)
·ArrayList<Integer>中的<Integer>念為typeof Integer
ArrayList稱為原始類型

二、泛型的使用
泛型的參數(shù)類型可以用在類酒繁、接口和方法的創(chuàng)建中滓彰,分別稱為泛型類、泛型接口和泛型方法州袒。下面看看具體是如何定義的揭绑。
1、泛型類的定義和使用
一個泛型類(generic class)就是具有一個或多個類型變量的類郎哭。定義一個泛型類十分簡單他匪,只需要在類名后面加上<>,再在里面加上類型參數(shù):
public static <T> ArrayList<T> empty() {
return new ArrayList<>();
}

public static <K, V> HashMap<K, V> emptyHashMap() {
    return new HashMap<>();
}

現(xiàn)在我們就可以使用這個泛型類了:
List<Map<String, Object>> list= ListUtil.empty();

2夸研、泛型接口的定義和使用
定義泛型接口和泛型類差不多邦蜜,看下面簡單的例子:
interface Show<T,U>{
void show(T t,U u);
}

class ShowTest implements Show<String,Date>{
@Override
public void show(String str,Date date) {
System.out.println(str);
System.out.println(date);
}
}
測試一下:
public static void main(String[] args) throws ClassNotFoundException {
ShowTest showTest=new ShowTest();
showTest.show("Hello",new Date());
}

3、泛型方法的定義和使用
泛型類在多個方法簽名間實施類型約束亥至。在 List<V> 中畦徘,類型參數(shù) V 出現(xiàn)在 get()、add()抬闯、contains() 等方法的簽名中。當(dāng)創(chuàng)建一個 Map<K, V> 類型的變量時关筒,您就在方法之間宣稱一個類型約束溶握。您傳遞給 add() 的值將與 get() 返回的值的類型相同。
類似地蒸播,之所以聲明泛型方法睡榆,一般是因為您想要在該方法的多個參數(shù)之間宣稱一個類型約束。
舉個簡單的例子:
public static void main(String[] args) throws ClassNotFoundException {
String str=get("Hello", "World");
System.out.println(str);
}

public static <T, U> T get(T t, U u) {
    if (u != null)
        return t;
    else
        return null;
}

三袍榆、泛型變量的類型限定
在上面胀屿,我們簡單的學(xué)習(xí)了泛型類、泛型接口和泛型方法包雀。我們都是直接使用<T>這樣的形式來完成泛型類型的聲明宿崭。
有的時候,類才写、接口或方法需要對類型變量加以約束葡兑〗甭看下面的例子:
有這樣一個簡單的泛型方法:
public static <T> T get(T t1,T t2) {
if(t1.compareTo(t2)>=0);//編譯錯誤
return t1;
}
因為,在編譯之前讹堤,也就是我們還在定義這個泛型方法的時候吆鹤,我們并不知道這個泛型類型T,到底是什么類型洲守,所以疑务,只能默認(rèn)T為原始類型Object。所以它只能調(diào)用來自于Object的那幾個方法梗醇,而不能調(diào)用compareTo方法知允。
可我的本意就是要比較t1和t2,怎么辦呢婴削?這個時候廊镜,就要使用類型限定,對類型變量T設(shè)置限定(bound)來做到這一點唉俗。
我們知道嗤朴,所有實現(xiàn)Comparable接口的方法,都會有compareTo方法虫溜。所以雹姊,可以對<T>做如下限定:
public static <T extends Comparable> T get(T t1,T t2) { //添加類型限定
if(t1.compareTo(t2)>=0);
return t1;
}

類型限定在泛型類、泛型接口和泛型方法中都可以使用衡楞,不過要注意下面幾點:
1吱雏、不管該限定是類還是接口,統(tǒng)一都使用關(guān)鍵字 extends
2瘾境、可以使用&符號給出多個限定巢块,比如
public static <T extends Comparable&Serializable> T get(T t1,T t2)
3吃引、如果限定既有接口也有類,那么類必須只有一個,并且放在首位置
public static <T extends Object&Comparable&Serializable> T get(T t1,T t2)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末铜跑,一起剝皮案震驚了整個濱河市趁尼,隨后出現(xiàn)的幾起案子谈为,更是在濱河造成了極大的恐慌盼产,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件礼华,死亡現(xiàn)場離奇詭異咐鹤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)圣絮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門祈惶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事行瑞〖橄伲” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵血久,是天一觀的道長突照。 經(jīng)常有香客問我,道長氧吐,這世上最難降的妖魔是什么讹蘑? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮筑舅,結(jié)果婚禮上座慰,老公的妹妹穿的比我還像新娘。我一直安慰自己翠拣,他們只是感情好版仔,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著误墓,像睡著了一般蛮粮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谜慌,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天然想,我揣著相機(jī)與錄音,去河邊找鬼欣范。 笑死变泄,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恼琼。 我是一名探鬼主播妨蛹,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼晴竞!你這毒婦竟也來了滑燃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤颓鲜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后典予,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甜滨,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年瘤袖,在試婚紗的時候發(fā)現(xiàn)自己被綠了衣摩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖艾扮,靈堂內(nèi)的尸體忽然破棺而出既琴,到底是詐尸還是另有隱情,我是刑警寧澤泡嘴,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布甫恩,位于F島的核電站,受9級特大地震影響酌予,放射性物質(zhì)發(fā)生泄漏磺箕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一抛虫、第九天 我趴在偏房一處隱蔽的房頂上張望松靡。 院中可真熱鬧,春花似錦建椰、人聲如沸雕欺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屠列。三九已至,卻和暖如春谅海,著一層夾襖步出監(jiān)牢的瞬間脸哀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工扭吁, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留撞蜂,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓侥袜,卻偏偏與公主長得像蝌诡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子枫吧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

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

  • 引言:泛型一直是困擾自己的一個難題浦旱,但是泛型有時一個面試時老生常談的問題;今天作者就通過查閱相關(guān)資料簡單談?wù)勛约簩?..
    cp_insist閱讀 1,847評論 0 4
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,267評論 0 16
  • 我們知道例隆,使用變量之前要定義甥捺,定義一個變量時必須要指明它的數(shù)據(jù)類型,什么樣的數(shù)據(jù)類型賦給什么樣的值镀层。 假如我們現(xiàn)在...
    今晚打肉山閱讀 986評論 0 1
  • 前言 泛型(Generics)的型變是Java中比較難以理解和使用的部分,“神秘”的通配符吴侦,讓我看了幾遍《Java...
    珞澤珈群閱讀 7,860評論 12 51
  • 前面屋休,由于對泛型擦除的思考,引出了對Java-Type體系的學(xué)習(xí)备韧。本篇劫樟,就讓我們繼續(xù)對“泛型”進(jìn)行研究: JDK1...
    賈博巖閱讀 5,166評論 3 28