Java的泛型和萬用字元

來源:互聯網
上載者:User

標籤:param   無限   except   限制   new t   array   junit   ret   定義   

泛型:
1.泛型類
    class A<T>{
    }
2.在建立執行個體時,需要為其類型變數賦值

3.泛型方法
    class A<T>{
        public T fun1(){}
        public void fun2(T t){}
        //以上兩個都不是泛型方法,他們是泛型類裡面的一個方法
        //探索方法要求需要在方法上有泛型的定義
        public <T> T fun3(){}//此為泛型方法
    }

    class B{
        public <T> fun1(){}//也為泛型方法,泛型方法不一定要在泛型類中
    }
*泛型方法和泛型類並沒有直接的關係,

4.泛型類的使用
    *泛型類中定義的泛型
        >可以在方法的傳回值中使用
        >可以在方法的參數中使用
        >可以在局部變數是使用
    class C<T>{
        public T fun1(){
            T t = ...//可以的
            new T()//不可以的,會報錯
        }
        public void fun2(T t){}
    }
簡單來記:泛型可以在左邊使用而不可以在右邊使用。

5.泛型的繼承和實現
    *子類不是泛型類:需要給父類傳遞一個具體的類型常量
        >此時父類中所有的泛型參數都會被此類型常量給替換掉
    *子類是泛型類:可以給父類傳遞一個具體的型別參數,也傳遞一個泛型參數
    class AA1 extends A<String>{}
    class AA2<E> extends A<E>{}


=========================================
=========================================
=========================================

泛型的萬用字元

1. 萬用字元使用的情境

  方法的形參!

2. 萬用字元的優點
  使方法更加通用!

3. 萬用字元分類
  無界通配:?
  子類限定:? extends Object
  父類限定:? super Integer

4. 萬用字元缺點
  使變數使用上不再方便
  無界:參數和傳回值為泛型的方法,不能使用!
  子類:參數為泛型的方法不能使用
  父類:傳回值為泛型的方法不能使用

5. 比較萬用字元
boolean addAll(Collection<E> c)

List<Number> numList = new ArrayList<Number>();
List<Integer> intList = new ArrayList<Integer>();
numList.addAll(intList);//addAll(Collection<Number> c), 傳遞的是List<Integer>,報錯


boolean addAll(Collection<? extends E> c)

List<Number> numList = new ArrayList<Number>();
List<Integer> intList = new ArrayList<Integer>();
numList.addAll(intList);//addAll(Collection<? extends Number> c), 傳遞的是List<Integer>,通過

 

代碼示範

 1 package genericity; 2  3 public class Demo1 { 4  5    class A<T>{ 6        private T t; 7        public T fun1(){ 8            return t; 9        }10        11        public void fun2(T t){12            13        }14        15    }//是泛型類16    17    class B extends A<String>{}//B就不是泛型類18    19    class C<E> extends A<Integer>{}//也是泛型類20    21    class D<E> extends A<E>{}//也是泛型類22    23    public void fun1(){24        D<String> d = new D<String>();//此時class D 和 class E 中的泛型都被String給替換了25    }26 }

 

 

  1 package genericity;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import org.junit.Test;  7   8 public class Demo2 {  9  10     @Test 11     public void fun1(){//集合和數組的較量 12         /* 13          * 第一次較量 14          * 數組:我可以建立一個什麼都可以存在的10空間 15          * 集合:我可以建立一個什麼都放而且無限的空間 16          */ 17         Object[] arr1 = new Object[10]; 18         List list1 = new ArrayList(); 19          20         /* 21          * 第二次較量 22          * 數組:我可以建立一個只存放String類型的10空間 23          * 集合:在以前我不行,不過現在我也可以,我可以建立一個只存放String類型的無限空間。 24          */ 25         String[] arr2 = new String[10]; 26         List<String> list2 = new ArrayList<String>(); 27          28         /* 29          * 第三次較量 30          * 數組:我可以使用Object[]來存在String[],但是arr3[0] = new Integer(100);//編程不報錯,運行報:ArrayStoreException 31          * 集合:因為泛型的擦除,直接不給我編譯通過 List<Object> list3 = new ArrayList<String>() 32          */ 33         Object[] arr3 = new String[10]; 34         arr3[0] = new Integer(100);//編程不報錯,運行報:ArrayStoreException 35          36 //        List<Object> list3 = new ArrayList<String>(); 37           /** 38            * 上面的代碼報錯,因為泛型只有編譯器認識,而JVM對泛型根本不識別,泛型會在 39            * 運行時擦除,如果上面代碼不報錯,而且運行時泛型又會擦除,那麼就好出現下面的笑話 40            * list.add(new Integer(100)),那麼數組就好笑話集合,你什麼東西都能放, 41            * 還有什麼限制,笑話。 42            *  43            * 然後我們把這個問題放大,對一個列印集合裡面資料的方法, 44            */ 45     } 46      47     public void fun2(){ 48         List<Integer> intList = new ArrayList<Integer>(); 49          50         List<String> strList = new ArrayList<String>(); 51 //        print1(intList);//直接報錯,原因和上面的一樣,因為有一個實參向形參賦值的過程,編譯器直接不讓通過 List<Object> list= intList=new ArrayList<Integer>(); 52         //思考:那每個不同類型的集合都需要不同的列印方法,那方法是也太多了,所以就有了萬用字元的出現 53          54         //這樣就可以使用通用的列印方法了 55         print2(intList); 56         print2(strList); 57     } 58      59     public void print1(List<Object> list){ 60          61     } 62      63     /** 64      * 這裡的?就是萬用字元 65      * @param list 66      */ 67     public void print2(List<?> list){ 68         /* 69          * 思考:雖然都可以調用了,但是卻帶來了一些參數使用上面的限制 70          */ 71 //        list.add(new Integer(100));//報錯,因為並不知道傳遞進來的到底是上面,如果是String,那編程通過就笑話了,add()作廢 72         Object obj = list.get(0);//其實這個參數可以使用的原因是因為Object為所有類的父類,不讓這個get()方法也作廢 73          74         /* 75          * 小結: 76          *      1、當使用萬用字元時,對泛型類中的參數為泛型的方法起到了副作用,不能再使用! 77          *      2、當使用萬用字元時,泛型類中傳回值為泛型的方法,也作廢了! 78          * 萬用字元的好處:可以使泛型型別更加通用!尤其是在方法調用時形參使用萬用字元! 79          */ 80     } 81      82     public void fun3(){ 83         List<Integer> intList = new ArrayList<Integer>(); 84         List<Long> longList = new ArrayList<Long>(); 85         print3(intList); 86         print3(longList); 87     } 88      89     /** 90      * 子類統配,必須是Number及Number的子類才可以傳參 91      * 這樣的缺點是:降低了參數的靈活性,但是關閉一扇大門就會開啟一扇大門 92      * 因為所有累都是Number的子類,所有傳回值可以使用Number來接受,get()方法獲得解放,即傳回值為泛型的方法可以使用了 93      * @param list 94      */ 95     public void print3(List<? extends Number> list){ 96         Number nu = list.get(0);//正確 97 //        list.add(new Integer(100));//但add()方法還是被廢,以為不知道具體傳入的哪一個子類,如果傳入的是Long,加入Integer就笑話了 98     } 99     100     /**101      * 父類統配,只允許Integer傳遞參數102      * 這樣的缺點是:降低了參數的靈活性,但是關閉一扇大門就會開啟一扇大門103      * 好處是因為所有類都是Integer的父類,參數為泛型的所有方法都可以使用了104      * 但是相反的,傳回值為泛型型別的方法就不能使用,因為子類不能接收父類的值105      * @param list106      */107     public void print4(List<? super Integer> list){108         list.add(new Integer(100));//正確109         /*110          * 但傳回值為泛型的方法就不能使用了111          */112 //        Integer nu = list.get(0);//報錯113     }114     115     116 }

 

Java的泛型和萬用字元

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.