Java進階(四)Java反射TypeToken解決泛型運行時類型擦除問題

      網友投稿 1168 2025-03-31

      在開發時,遇到了下面這條語句,不懂,然習之。


      private?List?listLottery?=?new?ArrayList();

      Gson?gson=new?Gson();

      JSONObject?object=new?JSONObject(callbackValue);

      listLottery?=??gson.fromJson(object.getString("lists"),

      Java進階(四)Java反射TypeToken解決泛型運行時類型擦除問題

      new?TypeToken>()?{

      }.getType());

      GSON提供了?TypeToken?這個類來幫助我們捕獲(capture)像List這樣的泛型信息。上文創建了一個匿名內部類,這樣,Java編譯器就會把泛型信息編譯到這個匿名內部類里,然后在運行時就可以被?getType()方法用反射API提取到。

      下面來看看gson的反序列化,Gson提供了fromJson()方法來實現從Json相關對象到java實體的方法。

      在日常應用中,我們一般都會碰到兩種情況,轉成單一實體對象和轉換成對象列表或者其他結構。

      先來看第一種:

      比如json字符串為:{"name":"name0","age":0}

      代碼:

      Person?person?=?gson.fromJson(str,?Person.class);

      提供兩個參數,分別是json字符串以及需要轉換對象的類型。

      第二種,轉換成列表類型:

      代碼:

      List?ps?=?gson.fromJson(str,?new?TypeToken>(){}.getType());

      for(int?i?=?0;?i?

      {

      Person?p?=?ps.get(i);

      System.out.println(p.toString());

      }

      可以看到上面的代碼使用了TypeToken,它是gson提供的數據類型轉換器,可以支持各種數據集合類型轉換。

      經過比較,gson和其他現有java?json類庫最大的不同是gson需要序列化的實體類不需要使用annotation來標識需要序列化得字段,同時gson又可以通過使用annotation來靈活配置需要序列化的字段。

      另外,java反射包中的TypeToken類是用來解決java運行時泛型類型被擦除的問題的,有點不好理解,我們通過一個例子來認識什么是泛型的運行時類型擦除。

      ArrayList?stringList?=?Lists.newArrayList();

      ArrayList?intList?=?Lists.newArrayList();

      System.out.println("intList?type?is?"?+?intList.getClass());

      System.out.println("stringList?type?is?"?+?stringList.getClass());

      System.out.println(stringList.getClass().isAssignableFrom(intList.getClass()));

      上面的代碼我們聲明了兩個泛型的ArrayList類型,一個泛型的類型參數是String,另外一個是Integer;然后我們輸出了兩個泛型的Class,并輸出兩個list的類型是否是同一個list。我們看下輸出的結果:

      intList?type?is?class?java.util.ArrayListstringList?type?is?class?java.util.ArrayListtrue

      前兩個輸出都是java.util.ArrayList,而第三個輸出竟然是true,也就是認為stringList和intList的類型是一樣的。這就是所謂的泛型類型擦除。運行時我們不知道泛型類型的類型參數是什么了。

      TypeToken可以解決這個問題,請看下面代碼:

      TypeToken>?typeToken?=?new?TypeToken>()?{};????????TypeToken?genericTypeToken?=?typeToken.resolveType(ArrayList.class.getTypeParameters()[0]);????????System.out.println(genericTypeToken.getType());

      注意上面第一行代碼使用了一個空的匿名類。第二行使用了resolveType方法解析出泛型類型,第三行代碼打印出泛型類型,輸出是:

      class?java.lang.String

      可以看出TypeToken解析出了泛型參數的具體類型。

      TypeToken的方法列表如下:

      方法

      描述

      getType()

      獲得包裝的java.lang.reflect.Type.

      getRawType()

      返回大家熟知的運行時類

      getSubtype(Class)

      返回那些有特定原始類的子類型。舉個例子,如果這有一個Iterable并且參數是List.class,那么返回將是List。

      getSupertype(Class)

      產生這個類型的超類,這個超類是指定的原始類型。舉個例子,如果這是一個Set并且參數是Iterable.class,結果將會是Iterable。

      isAssignableFrom(type)

      如果這個類型是?assignable?from?指定的類型,并且考慮泛型參數,返回true。List是assignable?from?List,但List沒有.

      getTypes()

      返回一個Set,包含了這個所有接口,子類和類是這個類型的類。返回的Set同樣提供了classes()和interfaces()方法允許你只瀏覽超類和接口類。

      isArray()

      檢查某個類型是不是數組,甚至是

      getComponentType()

      返回組件類型數組。

      Gson的基本使用就是這么多,至于annotation方面可以參考gson的官方文檔,希望能對初學java和gson的同學有所幫助。

      Java JSON

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:2021信息系統項目管理師預測
      下一篇:如何調整excel圖表的橫坐標間隔(excel2010橫坐標間隔調整)
      相關文章
      高清在线亚洲精品国产二区| 精品国产亚洲一区二区三区在线观看| 亚洲中文字幕伊人久久无码| 国产精品无码亚洲一区二区三区| 亚洲中文字幕一二三四区苍井空| 亚洲人成电影青青在线播放| 亚洲激情校园春色| 亚洲黄色三级网站| 亚洲精品欧洲精品| 亚洲成aⅴ人片在线影院八| 亚洲精品人成电影网| 亚洲成aⅴ人片在线影院八| 久久精品国产亚洲AV忘忧草18 | 亚洲一区动漫卡通在线播放| 亚洲性色高清完整版在线观看| 亚洲性一级理论片在线观看| 亚洲av永久无码精品三区在线4| 亚洲人成电影在线观看网| 国产精品亚洲自在线播放页码| 亚洲一区在线观看视频| 亚洲砖码砖专无区2023 | 亚洲欧洲无码AV不卡在线| 亚洲欧洲精品成人久久曰| 亚洲av午夜电影在线观看| 国产亚洲女在线线精品| 亚洲国产精品尤物YW在线观看| 亚洲国产电影av在线网址| 亚洲无码精品浪潮| 亚洲韩国精品无码一区二区三区 | 亚洲精品无码久久久久sm| 亚洲AV永久无码精品一百度影院| 亚洲AV乱码一区二区三区林ゆな| 久久久久亚洲Av无码专| 亚洲二区在线视频| 亚洲精品天堂无码中文字幕| 亚洲?V无码成人精品区日韩| 亚洲色欲久久久综合网| 亚洲成人激情在线| 亚洲宅男精品一区在线观看| 亚洲国产成人精品无码区花野真一 | 亚洲国产成人久久综合一|