泛型

[toc]

一、為什么要有泛型

1.1泛型:標簽

1.2 設(shè)計背景:

  • 集合容器設(shè)計階段或聲明階段不能確定這個容器到底實際存的是什么類型的對象棚瘟,所以在 JDK 1.5 之前 只能把元素類型設(shè)計為 ObjectJDK1.5 之后使用泛型來解決垦搬。
  • 泛型把元素的類型設(shè)計成一個參數(shù)孽惰,這個類型參數(shù)叫做泛型。
  • <font color=red>泛型迂烁,就是允許在定義類、接口時通過一個標識表示類中某個屬性的類型或者是某個方法的返回值及參數(shù)類型递鹉。這個類型參數(shù)將在使用時(例如盟步,繼承或?qū)崿F(xiàn)這個接口,用這個類型聲明變量躏结,創(chuàng)建對象)確定(即傳入實際的類型參數(shù)却盘,也成為類型實參)</font>

二、在集合中使用泛型

  • 集合接口或集合類在 jdk 5.0 時都修改為帶泛型的結(jié)構(gòu)

  • 在實例化集合類時媳拴,可以指明具體的<font color=red>泛型類型</font>

  • 指明完以后黄橘,在集合類或接口總凡是定義類或接口時,<font color=red>內(nèi)部結(jié)構(gòu)(比如:方法屈溉、構(gòu)造器塞关、屬性)</font>使用到類的泛型的位置,都指定為實例化的泛型類型子巾。比如 : add(E e) --> 實例化以后: add(Integer e)

  • 注意點:泛型的類型必須是類帆赢,不能是基本數(shù)據(jù)類型,需要用到基本數(shù)據(jù)類型的位置砰左,拿<font color=red>包裝類</font>替換

  • 如果實例化時匿醒,沒有指明泛型的類型,<font color=red>默認類型為 java.lang.Object </font>類型

2.1 在集合中使用 泛型前的情況:

  • 問題一:類型不安全
  • 問題二:強轉(zhuǎn)時缠导,可能出現(xiàn) ClassCastException

2.2 類型推斷

List<Integer> list = new ArrayList<>(); 

三、自定義泛型結(jié)構(gòu)

  • 泛型類溉痢、泛型接口僻造;泛型方法
  • 要求:如果定義了類是帶泛型的,建議在實例化時指明類的泛型

3.1 關(guān)于自定義泛型類孩饼、泛型接口

  • 自定義泛型類

    public class Order<T> {
    
        String orderName;
        int orderId;
    
        //類的內(nèi)部結(jié)構(gòu)就可以使用類的泛型
        T orderT;
    
        public Order(){}
    
        public Order(String orderName,int orderId,T orderT){
            this.orderName = orderName;
            this.orderId = orderId;
            this.orderT = orderT;
    
        }
    
        public T getOrderT(){
            return orderT;
        }
        public void setOrderT(T orderT){
            this.orderT = orderT;
        }
    
        @Override
        public String toString() {
            return "Order{" +
                    "orderName='" + orderName + '\'' +
                    ", orderId=" + orderId +
                    ", orderT=" + orderT +
                    '}';
        }
    }
    
  • 如果定義了泛型類髓削,實例化沒有指明類的泛型,則認為此泛型類型為Object 類型

    • 經(jīng)驗: 泛型要用就一直用镀娶,要不用立膛,就一直都不用
    Order order = new Order();
    order.setOrderT(123);
    order.setOrderT("ABC");
    
  • 建議:實例化時指明類的泛型

    Order<String> order1 = new Order<String>("orderAA",1001,"order:AA");
    
  • 泛型類可能有多個參數(shù),此時應(yīng)將多個參數(shù)一起放在 尖括號內(nèi)。比如< E1,E2,E3>

  • 泛型類的構(gòu)造器如下:

    public GenericClass(){}
    

    錯誤的是:

    public GenericClass<E>(){}
    
  • 實例化后宝泵,操作原來泛型位置的結(jié)構(gòu)必須與指定的泛型類型一致

  • 泛型不同的引用不能相互賦值

    • 盡管在編譯時ArrayList< String > 和 ArrayList< Integer> 是兩種類型好啰,但是,在運行時儿奶,只有一個ArrayList 被加載到 JVM 中框往。
    ArrayList<String> list1 = null;
    ArrayList<Integer> list2 = null;
    //list1 = list2;
    
  • 靜態(tài)方法中不能使用類的泛型,靜態(tài)方法創(chuàng)建早于泛型的創(chuàng)建闯捎,所以不能使用

  • 異常類不能聲明為泛型類

    • 錯誤的代碼

      //public class MyException<T> extends Exception{}
      
      /*try{
          
      }catch(T t){
          
      }*/
      
  • 不能使用new E[] .

    //編譯不通過
    //T[] arr = new T[10];
    //編譯通過
    T[] arr = (T[]) new Object();
    
  • 父類有泛型椰弊,子類可以選擇保留泛型也可以選指定泛型類型:

    class Father<T1,T2>{ }
    
    • 子類不保留父類的泛型:按需實現(xiàn)

      • 沒有類型 擦除

        class Son1 extends Father{
        //等價于 class Son extends Father<Object,Object>{}
        }
        
      • 具體類型

        class Son2 extends Father<Integer,String>{}
        
    • 子類保留父類的泛型 泛型子類

      • 全部保留

        class Son3<T1,T2> extends Father{}
        
      • 部分保留

        class Son4<T2> extends Father<Integer,T2>{}
        

3.2 泛型方法:

  • 方法中出現(xiàn)了泛型的結(jié)構(gòu)泛型參數(shù)與類的泛型參數(shù)沒有任何關(guān)系

  • 泛型方法所屬的類是不是泛型類都沒關(guān)系瓤鼻。

  • 泛型方法秉版,可以聲明為靜態(tài)的,原因:泛型參數(shù)是在調(diào)用方法時確定的茬祷。并非在實例化類時確定清焕。

    public <E> List<E> copyFromArrayToList(E[] arr){
        ArrayList<E> list = new ArrayList<>();
        for (E e : arr) {
            list.add(e);
        }
        return list;
    }
    

四、泛型在繼承上的體現(xiàn)

  • 雖然類 A 是類B 的父類牲迫,但是 G< A> 和 G< B> 二者不具備子父類關(guān)系耐朴,二者是并列關(guān)系。

  • 類A 是 類B 的父類盹憎,但是 G< A> 和 G< B> 是子父類關(guān)系

    AbstractList<String> list1 = null;
    List<String> list2 = null;
    ArrayList<String> list3 = null;
    
    list1 = list3;
    list2 = list3;
    
    List<String> list4 = new ArrayList<>();
    

五筛峭、通配符的使用

  • 通配符:?

  • 類A 是 類B 的父類陪每,G< A> 和 G< B> 是沒有關(guān)系的影晓,二者共同的父類是:G<?>

    @Test
    public void test3(){
        List<Object> list1 = null;
        List<Integer> list2 = null;
    
        List<?> list  = null;
    
        list = list1;
        list = list2;
    
        print(list1);
        print(list2);
    }
    
    public void print(List<?> list){
        Iterator<?> iterator = list.iterator();
        while(iterator.hasNext()){
            Object obj = iterator.next();
            System.out.println(obj);
        }
    }
    
  • 添加:對于 List<?> 就不能向其內(nèi)部添加數(shù)據(jù)。除了添加null之外

  • 獲乳莺獭:允許讀取數(shù)據(jù)挂签,讀取的數(shù)據(jù)類型為 Object

    List<?> list = null;
    List<Integer> list1 = new ArrayList<>();
    list.add(123);
    list = list1;
    Object o = list.get(0);
    System.out.println(o); //123
    

5.1 有限制條件的通配符

  • ? extends A: G< ? extends A> 可以作為 G< A> 和 G< B> 的父類的,其中B是A的子類盼产。

  • 饵婆? super A: G< ?super A> 可以作為 G< A> 和 G< B> 的父類戏售,其中 B 是 A 的父類侨核。

    List<? extends Person> list1 = null;
    List<? super Person> list2 = null;
    
    List<Student> list3 = null;
    List<Person> list4 = null;
    
    List<Object> list5 = null;
    
    list1 = list3;
    list1 = list4;
    //list1 = list5;
    
    //list2 = list3;
    list2 = list4;
    list2 = list5;
    

六、泛型應(yīng)用舉例

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末灌灾,一起剝皮案震驚了整個濱河市搓译,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锋喜,老刑警劉巖些己,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡段标,警方通過查閱死者的電腦和手機涯冠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怀樟,“玉大人功偿,你說我怎么就攤上這事⊥ぃ” “怎么了械荷?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長虑灰。 經(jīng)常有香客問我吨瞎,道長,這世上最難降的妖魔是什么穆咐? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任颤诀,我火速辦了婚禮,結(jié)果婚禮上对湃,老公的妹妹穿的比我還像新娘崖叫。我一直安慰自己,他們只是感情好拍柒,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布心傀。 她就那樣靜靜地躺著,像睡著了一般拆讯。 火紅的嫁衣襯著肌膚如雪脂男。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天种呐,我揣著相機與錄音宰翅,去河邊找鬼。 笑死爽室,一個胖子當著我的面吹牛汁讼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阔墩,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼掉缺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了戈擒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤艰毒,失蹤者是張志新(化名)和其女友劉穎筐高,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡柑土,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年蜀肘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稽屏。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡扮宠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狐榔,到底是詐尸還是另有隱情坛增,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布薄腻,位于F島的核電站收捣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏庵楷。R本人自食惡果不足惜罢艾,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望尽纽。 院中可真熱鬧咐蚯,春花似錦、人聲如沸弄贿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挎春。三九已至看疙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間直奋,已是汗流浹背能庆。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留脚线,地道東北人搁胆。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像邮绿,于是被迫代替她去往敵國和親渠旁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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