泛型的作用及使用場景

在沒有泛型之前庇勃,從集合讀取到的每一個對象都必須進行轉換脱柱。如果有人不小心插入了類型錯誤的對象,在運行時的轉換處理就會出錯披摄。有了泛型之后亲雪,可以告訴編譯器每個集合中接受哪些對象類型。編譯器自動地為你的插入進行轉化疚膊,并在編譯時告知是否插入了類型錯誤的對象义辕。這樣可以使程序既更安全,也更清楚寓盗。

《Effective Java》 第5章 泛型

語法

1. 普通使用

public class Point<T> {  
  
    private T data;  
  
    public T getData() {  
        return data;  
    }  
  
    public void setData(T data) {  
        this.data = data;  
    }  
}  

2. 受限

class Info<T extends Number>{    // 此處泛型只能是數(shù)字類型  
    private T var ;        // 定義泛型變量  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
    public String toString(){    // 直接打印  
        return this.var.toString() ;  
    }  
};  

3. 泛型接口(兩種寫法)

interface Info<T>{        // 在接口上定義泛型  
    public T getVar() ;    // 定義抽象方法灌砖,抽象方法的返回值就是泛型類型  
}  
class InfoImpl implements Info<String>{    // 定義泛型接口的子類  
    private String var ;                // 定義屬性  
    public InfoImpl(String var){        // 通過構造方法設置屬性內(nèi)容  
        this.setVar(var) ;      
    }  
    public void setVar(String var){  
        this.var = var ;  
    }  
    public String getVar(){  
        return this.var ;  
    }  
};  
interface Info<T>{        // 在接口上定義泛型  
    public T getVar() ;    // 定義抽象方法,抽象方法的返回值就是泛型類型  
}  
class InfoImpl<T> implements Info<T>{    // 定義泛型接口的子類  
    private T var ;                // 定義屬性  
    public InfoImpl(T var){        // 通過構造方法設置屬性內(nèi)容  
        this.setVar(var) ;      
    }  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
};  

4. 泛型方法

class Demo{  
    public <T> T fun(T t){            // 可以接收任意類型的數(shù)據(jù)  
        return t ;                    // 直接把參數(shù)返回  
    }  
};

5. 泛型數(shù)組

public class GenericsDemo{  
    public static void main(String args[]){  
        Integer i[] = fun1(1,2,3,4,5,6) ;    // 返回泛型數(shù)組  
        fun2(i) ;  
    }  
    public static <T> T[] fun1(T...arg){    // 接收可變參數(shù)  
        return arg ;            // 返回泛型數(shù)組  
    }  
    public static <T> void fun2(T param[]){    // 輸出  
        System.out.print("接收泛型數(shù)組:") ;  
        for(T t:param){  
            System.out.print(t + "傀蚌、") ;  
        }  
    }  
};  

6. 泛型嵌套

class Info<T,V>{        // 接收兩個泛型類型  
    private T var ;  
    private V value ;  
    public Info(T var,V value){  
        this.setVar(var) ;  
        this.setValue(value) ;  
    }  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public void setValue(V value){  
        this.value = value ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
    public V getValue(){  
        return this.value ;  
    }  
};  
class Demo<S>{  
    private S info ;  
    public Demo(S info){  
        this.setInfo(info) ;  
    }  
    public void setInfo(S info){  
        this.info = info ;  
    }  
    public S getInfo(){  
        return this.info ;  
    }  
};  

public class GenericsDemo{  
    public static void main(String args[]){  
        Demo<Info<String,Integer>> d = null ;        // 將Info作為Demo的泛型類型  
        Info<String,Integer> i = null ;    // Info指定兩個泛型類型  
        i = new Info<String,Integer>("李興華",30) ;     // 實例化Info對象  
        d = new Demo<Info<String,Integer>>(i) ;    // 在Demo類中設置Info類的對象  
        System.out.println("內(nèi)容一:" + d.getInfo().getVar()) ;  
        System.out.println("內(nèi)容二:" + d.getInfo().getValue()) ;  
    }  
}; 

注意

1. 泛型<?>基显、 <T>兩種寫法的區(qū)別

<?>是可以任意寫,不受限制,

<T> 如若泛型是聲明返回值的類型喳张,或者是聲明在類層次的

例如:

private static <T> T fun1(List<T> list) {
}

public interface Main<T> {
    public void fun(T t);
}
//然后

public class MainImpl<String> {
    @override
    public void fun(String str) {
    }
}

2续镇、子類無法使用父類的泛型類型進行接受

class Info<T>{  
    private T var ;        // 定義泛型變量  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
    public String toString(){    // 直接打印  
        return this.var.toString() ;  
    }  
};  
public class GenericsDemo23{  
    public static void main(String args[]){  
        Info<String> i1 = new Info<String>() ;   // 泛型類型為String  
        Info<Object> i2 = null ;  
        i2 = i1 ;  
    }  
};  

就會報如下錯誤:

GenericsDemo23.java:17: 不兼容的類型  
找到: Info<java.lang.String>  
需要: Info<java.lang.Object>  
                i2 = i1 ;  

3、如果同一方法參數(shù)使用泛型销部,應該保證泛型類型一致

class Info<T>{    // 指定上限摸航,只能是數(shù)字類型  
    private T var ;        // 此類型由外部決定  
    public T getVar(){  
        return this.var ;      
    }  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public String toString(){        // 覆寫Object類中的toString()方法  
        return this.var.toString() ;      
    }  
};  
public class GenericsDemo{  
    public static void main(String args[]){  
        Info<Integer> i1 = new Info<Integer>() ;  
        Info<String> i2 = new Info<String>() ;  
        i1.setVar(30) ;        // 設置內(nèi)容  
        i2.setVar("aoyoungboy") ;        // 設置內(nèi)容  
        add(i1,i2) ;  
    }  
    public static <T> void add(Info<T> i1,Info<T> i2){  
        System.out.println(i1.getVar() + " " + i2.getVar()) ;  
    }  
};  

就會報如下錯誤:

javac GenericsDemo.java  
GenericsDemo29.java:19: 無法將 GenericsDemo 中的 <T>add(Info<T>,Info<T>) 應用  
于 (Info<java.lang.Integer>,Info<java.lang.String>)  
add(i1,i2) ; 
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市舅桩,隨后出現(xiàn)的幾起案子酱虎,更是在濱河造成了極大的恐慌,老刑警劉巖擂涛,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件读串,死亡現(xiàn)場離奇詭異,居然都是意外死亡撒妈,警方通過查閱死者的電腦和手機恢暖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狰右,“玉大人杰捂,你說我怎么就攤上這事∑灏觯” “怎么了嫁佳?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谷暮。 經(jīng)常有香客問我蒿往,道長,這世上最難降的妖魔是什么湿弦? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任瓤漏,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘蔬充。我一直安慰自己俯在,他們只是感情好,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布娃惯。 她就那樣靜靜地躺著,像睡著了一般肥败。 火紅的嫁衣襯著肌膚如雪趾浅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天馒稍,我揣著相機與錄音皿哨,去河邊找鬼。 笑死纽谒,一個胖子當著我的面吹牛证膨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鼓黔,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼央勒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了澳化?” 一聲冷哼從身側響起崔步,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缎谷,沒想到半個月后井濒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡列林,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年瑞你,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片希痴。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡者甲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出润梯,到底是詐尸還是另有隱情过牙,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布纺铭,位于F島的核電站寇钉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏舶赔。R本人自食惡果不足惜扫倡,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撵溃,春花似錦疚鲤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至语淘,卻和暖如春诲宇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惶翻。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工姑蓝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吕粗。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓纺荧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親颅筋。 傳聞我的和親對象是個殘疾皇子宙暇,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

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