泛型

聲明中存在一個或者多個參數類型的類或者接口叫作泛型類或者接口。java

無限制的通配符類型:?安全

有限制的通配符類型: ? extends E dom

原生態類型:List  code

List 和 List<?> : 通配符類型是安全的,原生態類型是不安全的,原生態表明能夠將任何類型的數據放進去,可是通配符就不能。遞歸

不要在新代碼中使用原生態類型,這條規則有兩個例外。接口

一、在類文字中必須使用原生態類型。get

    List.class  String[].class  Test.class 等等合法  可是List<?>.class 則不合法源碼

二、<E extends Numer> 要求實際的參數類型E必須是Numer的一個子類型,包括自身。it

三、泛型方法io

    public static <E> Set<E> union (Set<E> s1,Set<E> s2){...}

                         <E> 表明類型參數列表

                          Set<E> 表明返回類型

四、遞歸類型限制。

    經過某個包含該類型參數自己的表達式來限制類型參數是容許的,這就是遞歸類型限制。

五、PECS原則:

  • 若是要從集合中讀取類型T的數據,而且不能寫入,能夠使用 ? extends 通配符;(Producer Extends)
  • 若是要從集合中寫入類型T的數據,而且不須要讀取,能夠使用 ? super 通配符;(Consumer Super)
  • 若是既要存又要取,那麼就不要使用任何通配符。

jdk 源碼示例:

  • public static <T> void copy(List<? super T> dest, List<? extends T> src) {
            int srcSize = src.size();
            if (srcSize > dest.size())
                throw new IndexOutOfBoundsException("Source does not fit in dest");
    
            if (srcSize < COPY_THRESHOLD ||
                (src instanceof RandomAccess && dest instanceof RandomAccess)) {
                for (int i=0; i<srcSize; i++)
                    dest.set(i, src.get(i));
            } else {
                ListIterator<? super T> di=dest.listIterator();
                ListIterator<? extends T> si=src.listIterator();
                for (int i=0; i<srcSize; i++) {
                    di.next();
                    di.set(si.next());
                }
            }
        }
相關文章
相關標籤/搜索