日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java泛型:类型擦除

發布時間:2025/3/21 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java泛型:类型擦除 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前情回顧

Java泛型:泛型類、泛型接口和泛型方法

類型擦除

代碼片段一

1 2 3 4 5 6 7 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String>().getClass(); System.out.println(c1 == c2);/* Output true */

顯然在平時使用中,ArrayList<Integer>()和new ArrayList<String>()是完全不同的類型,但是在這里,程序卻的的確確會輸出true。

這就是Java泛型的類型擦除造成的,因為不管是ArrayList<Integer>()還是new ArrayList<String>(),都在編譯器被編譯器擦除成了ArrayList。那編譯器為什么要做這件事?原因也和大多數的Java讓人不爽的點一樣——兼容性。由于泛型并不是從Java誕生就存在的一個特性,而是等到SE5才被加入的,所以為了兼容之前并未使用泛型的類庫和代碼,不得不讓編譯器擦除掉代碼中有關于泛型類型信息的部分,這樣最后生成出來的代碼其實是『泛型無關』的,我們使用別人的代碼或者類庫時也就不需要關心對方代碼是否已經『泛化』,反之亦然。

在編譯器層面做的這件事(擦除具體的類型信息),使得Java的泛型先天都存在一個讓人非常難受的缺點:

在泛型代碼內部,無法獲得任何有關泛型參數類型的信息。

代碼片段二

1 2 3 4 5 6 7 8 9 List<Integer> list = new ArrayList<Integer>(); Map<Integer, String> map = new HashMap<Integer, String>(); System.out.println(Arrays.toString(list.getClass().getTypeParameters())); System.out.println(Arrays.toString(map.getClass().getTypeParameters()));/* Output [E] [K, V] */

關于getTypeParameters()的解釋:

Returns an array of TypeVariable objects that represent the type variables declared by the generic declaration represented by this GenericDeclaration object, in declaration order. Returns an array of length 0 if the underlying generic declaration declares no type variables.

我們期待的是得到泛型參數的類型,但是實際上我們只得到了一堆占位符。

代碼片段三

1 2 3 4 5 6 7 public class Main<T> {public T[] makeArray() {// error: Type parameter 'T' cannot be instantiated directlyreturn new T[5];} }

我們無法在泛型內部創建一個T類型的數組,原因也和之前一樣,T僅僅是個占位符,并沒有真實的類型信息,實際上,除了new表達式之外,instanceof操作和轉型(會收到警告)在泛型內部都是無法使用的,而造成這個的原因就是之前講過的編譯器對類型信息進行了擦除。

同時,面對泛型內部形如T var;的代碼時,記得多念幾遍:它只是個Object,它只是個Object……

代碼片段四

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Main<T> {private T t;public void set(T t) {this.t = t;}public T get() {return t;}public static void main(String[] args) {Main<String> m = new Main<String>();m.set("findingsea");String s = m.get();System.out.println(s);} }/* Output findingsea */

雖然有類型擦除的存在,使得編譯器在泛型內部其實完全無法知道有關T的任何信息,但是編譯器可以保證重要的一點:內部一致性,也是我們放進去的是什么類型的對象,取出來還是相同類型的對象,這一點讓Java的泛型起碼還是有用武之地的。

代碼片段四展現就是編譯器確保了我們放在t上的類型的確是T(即便它并不知道有關T的任何類型信息)。這種確保其實做了兩步工作:

  • set()處的類型檢驗
  • get()處的類型轉換

這兩步工作也成為邊界動作

代碼片段五

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class Main<T> {public List<T> fillList(T t, int size) {List<T> list = new ArrayList<T>();for (int i = 0; i < size; i++) {list.add(t);}return list;}public static void main(String[] args) {Main<String> m = new Main<String>();List<String> list = m.fillList("findingsea", 5);System.out.println(list.toString());} }/* Output [findingsea, findingsea, findingsea, findingsea, findingsea] */

代碼片段五同樣展示的是泛型的內部一致性。

擦除的補償

如上看到的,但凡是涉及到確切類型信息的操作,在泛型內部都是無法共工作的。那是否有辦法繞過這個問題來編程,答案就是顯示地傳遞類型標簽。

代碼片段六

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Main<T> {public T create(Class<T> type) {try {return type.newInstance();} catch (Exception e) {e.printStackTrace();}return null;}public static void main(String[] args) {Main<String> m = new Main<String>();String s = m.create(String.class);} }

代碼片段六展示了一種用類型標簽生成新對象的方法,但是這個辦法很脆弱,因為這種辦法要求對應的類型必須有默認構造函數,遇到Integer類型的時候就失敗了,而且這個錯誤還不能在編譯器捕獲。

進階的方法可以用限制類型的顯示工廠和模板方法設計模式來改進這個問題,具體可以參見《Java編程思想 (第4版)》P382。

代碼片段七

1 2 3 4 5 6 7 8 9 10 11 public class Main<T> {public T[] create(Class<T> type) {return (T[]) Array.newInstance(type, 10);}public static void main(String[] args) {Main<String> m = new Main<String>();String[] strings = m.create(String.class);} }

代碼片段七展示了對泛型數組的擦除補償,本質方法還是通過顯示地傳遞類型標簽,通過Array.newInstance(type, size)來生成數組,同時也是最為推薦的在泛型內部生成數組的方法。

以上,泛型的第二部分的結束。

原文作者:?findingsea

原文鏈接:?http://findingsea.github.io/2015/10/09/java-generic-type-erasure/

總結

以上是生活随笔為你收集整理的Java泛型:类型擦除的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: xx色综合 | 久久网站免费 | 久久网站免费 | wwwxxx黄色| 国产精品视频亚洲 | 97伊人久久| 手机看黄色 | av高清不卡| 桃色一区二区 | www四虎精品视频免费网站 | 久久精品久久精品 | 快灬快灬一下爽69 | 爱爱视频天天干 | 色先锋在线 | 久久资源365 | 日韩免费视频一区 | 久久久久久一级片 | 美丽的姑娘在线观看免费 | 国产一av | 91午夜视频在线观看 | 免费网站www在线观看 | 欧美黑人精品 | 天天躁夜夜躁狠狠躁 | 国产精品一二三区视频 | 一区免费视频 | 尤物视频免费观看 | 一级黄色免费看 | 亚洲影视一区二区三区 | 亚洲精品久久久 | 亚洲熟妇无码一区二区三区 | 中文字幕久热 | 久久毛片网站 | c逼| 日韩欧美日本 | 在线观看中文字幕亚洲 | 天狂传说之巴啦啦小魔仙 | 在线欧美激情 | 久久婷香 | 国内成人精品视频 | 午夜免费视频 | 久久久久无码精品国产 | 老妇高潮潮喷到猛进猛出 | 国产永久免费视频 | 国产精品成人久久久 | 黄色片a级 | 欧美与黑人午夜性猛交久久久 | 黄色大片视频 | 中国白嫩丰满人妻videos | 日韩欧美一区二区一幕 | 一区久久久 | 美女大bxxxxn内射 | 天天夜夜啦啦啦 | 伊人色网 | 久久久夜夜 | 国产精品激情偷乱一区二区∴ | 伊人国产女 | 欧美黄网在线观看 | 久久色网站 | 欧美久久久久 | 黄色一级视频免费观看 | 国产靠逼视频 | 欧美激情视频一区二区 | 国产99在线| 福利姬在线观看 | 欧美日韩一区三区 | 青青91| 国产色网 | 免费在线激情视频 | 中文字幕日韩一区二区 | 四虎精品一区 | 色就是色网站 | 欧洲成人免费视频 | 欧美香蕉视频 | 日本吃奶摸下激烈网站动漫 | av中文字幕av | 这里只有精品视频在线 | 中国精品毛片 | 日本免费网址 | 日韩中文字幕在线观看视频 | 色婷婷免费视频 | 国产色婷婷一区二区三区竹菊影视 | 中国一级特黄毛片大片 | 在线天堂网 | 天天爱天天色 | 欧美激情亚洲色图 | 国产色站| 性欧美大战久久久久久久久 | 日本韩国视频 | 夜av | 日日热| 好男人www| 最近最经典中文mv字幕 | 亚洲天堂av中文字幕 | 二区视频在线观看 | 精品无码国产一区二区三区51安 | 极品粉嫩国产18尤物 | 老司机福利精品 | 国产肉丝在线 | 91手机在线|