Java 泛型小結

來源:互聯網
上載者:User

標籤:generics   class   lock   table   報錯   萬用字元   x11   直接   add   

1、什麼是泛型?

 

泛型(Generics )是把型別參數化,運用於類、介面、方法中,可以通過執行泛型型別調用 分配一個類型,將用分配的具體類型替換泛型型別。然後,所分配的類型將用於限制容器內使用的值,這樣就無需進行類型轉換,還可以在編譯時間提供更強的類型檢查。 

 

2、泛型有什麼用?

 

泛型主要有兩個好處:

 

(1)消除顯示的強制類型轉換,提高代碼複用

 

(2)提供更強的類型檢查,避免運行時的ClassCastException

 

3、泛型的使用

 

型別參數(又稱類型變數)用作預留位置,指示在運行時為類配置類型。根據需要,可能有一個或多個型別參數,並且可以用於整個類。根據慣例,型別參數是單個大寫字母,該字母用於指示所定義的參數類型。下面列出每個用例的標準型別參數:

 

E:元素

K:鍵

N:數字

T:類型

V:值

S、U、V 等:多參數情況中的第 2、3、4 個類型

? 表示不確定的java類型(無限制萬用字元類型)

 

4、有界泛型

<? extends T>:是指 “ 上界萬用字元 (Upper Bounds Wildcards) ”

 

<? super T>:是指 “ 下界萬用字元 (Lower Bounds Wildcards) ”

 

—這裡有個坑

如 List<? extends T> 大家以為元素為 T以及其所有子類的對象 的List。其實不是。元素類型 僅指T的某一個不確定的子類,是單一的一個不確定類,沒有具體哪個類。因此不能插入一個不確定的。

 

List<? super T> 大家以為元素為 T以及其父類的對象 的List。其實不是,元素類型 僅指T的某一個不確定的父類,是單一的一個不確定類(只確定是T的父類),沒有具體哪個類。

 

因此:

 

不能往List<? extends T>中插入任何類型的對象。唯一可以保證的是,你可以從中讀取到T或者T的子類。

 

可以往List<? super T>中插入T或者T子類的對象,但不可以插入T父類的對象。可以讀取到Object或者Object子類的對象(你並不知道具體的子類是什麼)

總結一下:

如果頻繁支援讀取資料,不要求寫資料,使用<? extends T>。即生產者 使用 <? extends T>;

如果頻繁支援寫入資料,不特別要求讀資料,使用<? super T>。即消費者 使用 <? super T>;

如果都需要支援,使用<T>。 

5、類型擦除

Java的泛型在編譯期間,所有的泛型資訊都會被擦除掉。 

  • Class c1 = new ArrayList<Integer>().getClass();  

    Class c2 = new ArrayList<Long>().getClass();   

    System.out.println(c1 == c2); 

    這就是 Java 泛型的類型擦除造成的,因為不管是 ArrayList<Integer> 還是 ArrayList<Long>,在編譯時間都會被編譯器擦除成了 ArrayList。Java 之所以要避免在建立泛型執行個體時而建立新的類,從而避免運行時的過度消耗。

6、泛型型別資訊 

  • 那麼,如果我們確實某些情境,如HTTP或RPC或jackson需要擷取泛型進行序列化還原序列化的時候,需要擷取泛型型別資訊。

     

    可以參照如下:

  • ?
    1234567891011121314151617181920212223242526272829303132 //擷取運行時的泛型型別資訊public class Test2 {      static class ParameterizedTypeReference<T> {        protected final Type type;          public ParameterizedTypeReference() {            Type superClass = this.getClass().getGenericSuperclass();            //if (superClass instanceof Class) {    // throw new IllegalArgumentException(//"Internal error: TypeReference constructed without actual type information");            //  } else {                this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];            //}        }          public Type getType() {            return type;        }    }      public static void main(String[] args) {// System.out.println(new ParameterizedTypeReference<String>().getType());// java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType// 此處會輸出報錯,因此ParameterizedTypeReference 應不能直接執行個體化,可以考慮加abstract          System.out.println(new ParameterizedTypeReference<String>() { }.getType());// ParameterizedTypeReference 的匿名內部類,可以觸發super(),//即 ParameterizedTypeReference()的構造器邏輯,正常運行    }  }

      

  • 注意一個關鍵點:

     

    可以通過定義類的方式(通常為匿名內部類,因為我們建立這個類只是為了獲得泛型資訊)在運行時獲得泛型參數。

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.