Java 泛型使用規(guī)則

本部分主要介紹:Java 的泛型、泛型通配符使用的規(guī)則和注意事項(xiàng)

泛型總結(jié)

  1. 泛型是 JDK 1.5 出現(xiàn)的技術(shù)道川,是為了 Java 安全性考慮累铅。泛型即限定類型的使用,將運(yùn)行時(shí)異常提前到編譯時(shí)異常蚤吹。
  2. 泛型可以在定義類、方法和接口上
    • 類中泛型不能創(chuàng)建對(duì)象 T t = new T() 随抠,因?yàn)榉盒褪遣淮_定的類型裁着,即無(wú)法開(kāi)辟空間
    • 接口的泛型不能是成員變量。接口的成員變量的修飾符 public static final 與泛型的使用規(guī)則相違背(即不確定類型拱她,如何成為靜態(tài)常量二驰,為實(shí)現(xiàn)類提供規(guī)則呢!)
    • 定義泛型可以不使用椭懊,不使用時(shí)默認(rèn)是 Obejct 類型
  3. 泛型通配符 只適用于方法定義時(shí)的 方法的形參 (不是調(diào)用方法的傳入的實(shí)參)以復(fù)用代碼為目的

泛型出現(xiàn)的目的

  1. 泛型的本質(zhì)

    • 類型參數(shù)化诸蚕,將類型當(dāng)作參數(shù)步势。
    • 在定義類或集合(當(dāng)然集合是 Java 自帶的)時(shí)氧猬,不指定元素的明確類型,直到創(chuàng)建對(duì)象或集合時(shí)坏瘩,才明確對(duì)象或集合中的元素類型盅抚。
  2. 泛型的好處

    • 限定類型,避免類型轉(zhuǎn)換錯(cuò)誤

    • 可以把異常從運(yùn)行時(shí)期提到編譯時(shí)期

    • 與集合連用倔矾,不需要轉(zhuǎn)換類型

      ArrayList<String> list = new ArrayList<String>(); // 泛型完整的寫法
      // ArrayList<String> list = new ArrayList(); // 泛型的簡(jiǎn)化寫法
      list.add("ab.c");
      list.get(0).split("\\."); // 可以直接調(diào)用 String 方法妄均,不需要轉(zhuǎn)換
      
  3. 泛型與 Object 相比,限定類型的使用

    • 集合在明確泛型類型時(shí)哪自,默認(rèn)使用的是 Object 類型丰包,即可以接受 Java 的所有類型。

    • 在 Java 中 Object 類是所有類的父類壤巷,Object 可以接受所有類型(8 中基本類型除外)邑彪。當(dāng)向集合添加元素時(shí) 向上轉(zhuǎn)型Object 類型,當(dāng)取出元素時(shí) 向下轉(zhuǎn)型胧华,如下寄症,編譯器并不會(huì)報(bào)錯(cuò),只有在運(yùn)行時(shí)矩动,才會(huì)報(bào) CalssCastExecption 異常有巧。

      ArrayList list = new ArrayList(); // 沒(méi)有指定泛型,實(shí)際默認(rèn)是以 Object 類型接受
      list.add(1); // 編譯不會(huì)報(bào)錯(cuò)
      list.add("abc"); // 編譯不會(huì)報(bào)錯(cuò)
      // 當(dāng)取出集合元素時(shí)悲没,編譯并不會(huì)報(bào)錯(cuò)篮迎;運(yùn)行時(shí)報(bào)錯(cuò)
      String str = (String) list.get(0);
      String in = (String) list.get(1);
      
    • 而泛型就是將類型做限定(只有在類型限定范圍能,才可以使用),將錯(cuò)誤提示發(fā)生在編譯時(shí)期(這也是 Java 一直在做的甜橱,將運(yùn)行時(shí)期錯(cuò)誤享言,提到編譯時(shí)期)。如下渗鬼,泛型限定 String 览露,向其添加 Integer 編譯時(shí)期就會(huì)報(bào)錯(cuò)。

      ArrayList<String> list = new ArrayList<String>();
      list.add(1); //編譯時(shí)期譬胎,直接提示錯(cuò)誤差牛,這樣對(duì)集合就做了類型的限定
      

泛型的注意事項(xiàng)

  1. 泛型格式

    • 數(shù)據(jù)類型<泛型的類型> 對(duì)象 = new 數(shù)據(jù)類型<泛型的類型>();

    • 泛型一般與集合連用較多,正常書寫方法(等號(hào)兩邊的泛型如果寫堰乔,就必須保持一致)

      ArrayList<String> list = new ArrayList<String>();
      
    • 簡(jiǎn)化寫法(jdk 1.7 出現(xiàn)的特性偏化,依據(jù)右側(cè)推測(cè)左側(cè)的類型)

      ArrayList<String> list = new ArrayList();
      
    • 介紹泛型以下幾種寫法(與集合連用)

      1. 泛型推斷,等號(hào)左邊寫泛型镐侯,右邊可以不寫泛型侦讨。等號(hào)左邊是完整的泛型定義,可以從左邊推斷出右邊的泛型類型苟翻,集合只能添加 String 類型

        ArrayList<String> list = new ArrayList<>();
        list.add("abc"); //正確
        list.add(new Integer(1)); // 錯(cuò)誤
        
      2. 等號(hào)右邊寫泛型韵卤,左邊不寫。這樣就如同沒(méi)有泛型崇猫,任何類型都可以添加沈条。

        ArrayList list = new ArrayList<String>();
        list.add("abc"); // 正確
        list.add(new Integer(1)); // 正確
        
  2. 通配符注意

    • 泛型通配符 不適用 于集合對(duì)象的創(chuàng)建
    • 泛型通配符 適用 于方法的形參上

泛型類、方法诅炉、接口

  1. 泛型類

    • 泛型類定義

      public class GenericType<T> {
          // <T> 就是形參
          //也可以定義多個(gè)泛型 <T, E>
          T t;
      }
      
    • 類中的泛型蜡歹,不能創(chuàng)建對(duì)象 T t = new T() √樯眨可以這樣理解:泛型是參數(shù)化類型月而,類中的泛型就是參數(shù),在沒(méi)有明確實(shí)參的情況议纯,泛型怎么可以創(chuàng)建對(duì)象呢父款!。

    • 實(shí)例化對(duì)象時(shí)痹扇,在沒(méi)有明確泛型類型時(shí)铛漓,泛型類型默認(rèn)為 Object

  2. 泛型接口

    • 泛型接口定義

      public interface GenericInter<T, E> {
          // <T> 就是形參
          //也可以定義多個(gè)泛型 <T, E>
          //T t; // 錯(cuò)誤
          public abstract void method1(T t);
          public abstract void method2(E e);
      }
      
    • 泛型接口不可以定義成員變量 T t; ■旯梗可以這樣理解:接口的成員都是 public static final 修飾的浓恶,這是接口的特性(提供規(guī)則,子類必須遵循结笨,不可以更改)包晰。泛型接口湿镀,泛型沒(méi)有明確類型時(shí),就不能向子類提供規(guī)則伐憾。相反勉痴,則違背了接口的規(guī)則。

    • 泛型接口树肃,只會(huì)體現(xiàn)在接口的方法中

      public abstract void method(T t);
      
    • 實(shí)現(xiàn)接口的 3 中方式

      1. 實(shí)現(xiàn)接口時(shí)蒸矛,無(wú)泛型,默認(rèn)使用 Object 類型

        public class GenericType implements GenericInter {
        
            @Override
            public void method1(Object t) {
            }
        
            @Override
            public void method2(Object e) {
            }
        }
        
      2. 實(shí)現(xiàn)接口時(shí)胸嘴,實(shí)現(xiàn)類使用泛型雏掠,但未明確泛型類型時(shí),實(shí)現(xiàn)類與接口的泛型必須保持一致(此類稱之為泛型類)

        public class GenericType<T, E> implements GenericInter<T, E> {
        
            @Override
            public void method1(E t) {
            }
        
            @Override
            public void method2(T e) {
            }
        }
        
      3. 實(shí)現(xiàn)接口時(shí)劣像,就明確類型

        public class GenericType implements GenericInter<String, Integer> {
        
            @Override
            public void method1(Integer t) {
            }
        
            @Override
            public void method2(String e) {
            } 
        }
        
  3. 泛型方法

    • 泛型方法定義乡话,泛型定義在方法的返回類型前面

      class GenericMethod {
          public <T> void method(T t) {  
          }
      }
      
    • 泛型方法使用

      GenericMethod g = new GenericMethod();
      g.method("abc"); // 調(diào)用方法時(shí),傳入泛型確定類型
      

泛型通配符

  1. 通配符的種類

    • ? 任意類型耳奕,沒(méi)有明確那就是 Object 以及任意的 Java 類型
    • ? extends E 向下限定绑青,E 及其子類
    • ? super E 向上限定,E 及其父類
  2. 通配符使用場(chǎng)景

    • 通配符的使用場(chǎng)景是方法的 形參上 屋群,表示方法可以接受的數(shù)據(jù)類型

      public void method(ArrayList<? extends People> list) {
          
      }
      
    • 泛型通配符不是用在對(duì)象定義上

      1. 如集合

        // 語(yǔ)法報(bào)錯(cuò)
        ArrayList<?> list = new ArrayList<?>();
        ArrayList<? extends People> list = new ArrayList<? entends People>();
        ArrayList<? super Student> list = new ArrayList<? super Student>();
        
        // 任何元素都添加不上闸婴,除了 null
        ArrayList<?> list = new ArrayList<>();
        // 任何元素都添加不上,除了 null
        ArrayList<? extends People> list = new ArrayList<>();
        // 可以添加 Student以及子類
        ArrayList<? super Student> list = new ArrayList<>();
        
      2. 在類上使用谓晌、在接口上使用掠拳、在調(diào)用方法時(shí)癞揉,都會(huì)發(fā)生語(yǔ)法錯(cuò)誤

  3. 通配符出現(xiàn)的原因

    • 數(shù)組有協(xié)變纸肉,集合沒(méi)有協(xié)變

    • 協(xié)變

      1. Student extends People ,那么 Peole[] 兼容 Studnet[]喊熟。

      2. 集合使用泛型之后是不能協(xié)變柏肪,ArrayList<People> 不是 ArrayList<Student> 父類,當(dāng)然也不可以兼容的

      3. 集合想要兼容芥牌,通配符解決了這個(gè)問(wèn)題烦味。StudentPeople 都可以當(dāng)此方法的實(shí)參

        public void method(ArrayList<? extends People> list) {
            
        }
        
    • 問(wèn)題的提出

      1. 定義 兩個(gè)類, Student 類繼承 People

      2. 定義兩個(gè)數(shù)組和兩個(gè)集合

        Student[] stu = new Studnet[2];
        People[] p = new Peoplep[2];
        
        ArrayList<People> list = new ArrayList<People>();
        ArrayList<Student> list1 = new ArrayList<>();
        
      3. 定義兩個(gè)方法

        public void method1(People[] people){
            
        }
        
        public void method2(List<People> liat) {
            
        }
        
      4. 調(diào)用兩個(gè)方法

        method1(p);
        method1(stu); // 類型兼容
        
        method2(list);
        method2(list1); // 類型不兼容
        
    • 解決辦法

      1. 通配符的出現(xiàn)

        • 修改 method2 方法壁拉,表示 People 及其子類都兼容

          public void method2(List<? extends People> liat) {
              
          }
          
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谬俄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子弃理,更是在濱河造成了極大的恐慌溃论,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痘昌,死亡現(xiàn)場(chǎng)離奇詭異钥勋,居然都是意外死亡炬转,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門算灸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扼劈,“玉大人,你說(shuō)我怎么就攤上這事菲驴〖龀常” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵赊瞬,是天一觀的道長(zhǎng)捍靠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)森逮,這世上最難降的妖魔是什么榨婆? 我笑而不...
    開(kāi)封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮褒侧,結(jié)果婚禮上良风,老公的妹妹穿的比我還像新娘。我一直安慰自己闷供,他們只是感情好烟央,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著歪脏,像睡著了一般疑俭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上婿失,一...
    開(kāi)封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天钞艇,我揣著相機(jī)與錄音,去河邊找鬼豪硅。 笑死哩照,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的懒浮。 我是一名探鬼主播飘弧,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼砚著!你這毒婦竟也來(lái)了次伶?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤稽穆,失蹤者是張志新(化名)和其女友劉穎冠王,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秧骑,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡版确,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年扣囊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绒疗。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侵歇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吓蘑,到底是詐尸還是另有隱情惕虑,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布磨镶,位于F島的核電站溃蔫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏琳猫。R本人自食惡果不足惜伟叛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脐嫂。 院中可真熱鬧统刮,春花似錦、人聲如沸账千。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)匀奏。三九已至鞭衩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娃善,已是汗流浹背论衍。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留会放,地道東北人饲齐。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像咧最,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子御雕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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

  • 一矢沿、泛型簡(jiǎn)介1.引入泛型的目的 了解引入泛型的動(dòng)機(jī),就先從語(yǔ)法糖開(kāi)始了解酸纲。 語(yǔ)法糖 語(yǔ)法糖(Syntactic S...
    Android進(jìn)階與總結(jié)閱讀 1,029評(píng)論 0 9
  • 集合是Java中提供的一種容器愁溜,可以用來(lái)存儲(chǔ)多個(gè)數(shù)據(jù),可以對(duì)其中的數(shù)據(jù)進(jìn)行操作 一外厂、集合繼承關(guān)系 由上圖可以看到冕象,...
    叢鵬閱讀 489評(píng)論 0 0
  • 開(kāi)發(fā)人員在使用泛型的時(shí)候,很容易根據(jù)自己的直覺(jué)而犯一些錯(cuò)誤汁蝶。比如一個(gè)方法如果接收List作為形式參數(shù)渐扮,那么如果嘗試...
    時(shí)待吾閱讀 1,055評(píng)論 0 3
  • 為什么是object 我們都知道object是所有類的超類,那么在早期沒(méi)有泛型概念的時(shí)候 其實(shí)就是用object來(lái)...
    金色888閱讀 517評(píng)論 0 0
  • 曾經(jīng)以為墓律,放下一個(gè)人,會(huì)很簡(jiǎn)單幔亥。 可以沒(méi)心沒(méi)肺耻讽,可以故作灑脫,可以對(duì)酒當(dāng)歌帕棉,花前明月齐饮。一個(gè)人的時(shí)候,突然的笤昨,思念和...
    房簡(jiǎn)悅閱讀 465評(píng)論 2 2