日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
當(dāng)JSON解析遇上了泛型,該如何處理泛型擦除問(wèn)題

JSON是一種輕量級(jí)的數(shù)據(jù)交換格式,簡(jiǎn)潔和清晰的層次結(jié)構(gòu)使得 JSON 成為理想的數(shù)據(jù)交換語(yǔ)言,常被用于實(shí)際項(xiàng)目中。Java生態(tài)圈中有很多處理JSON格式化的類(lèi)庫(kù),如json-lib框架、Jackson、Google的Gson、阿里的FastJson等,通過(guò)這些類(lèi)庫(kù)可以使我們更加簡(jiǎn)便地處理JSON。下面本文主要通過(guò)一個(gè)實(shí)際案例討論分析在解析JSON字符串的過(guò)程中遇到泛型該如何處理。

網(wǎng)站設(shè)計(jì)、網(wǎng)站制作中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細(xì)微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準(zhǔn)用戶(hù),提高在線(xiàn)咨詢(xún)和轉(zhuǎn)化,使成都網(wǎng)站營(yíng)銷(xiāo)成為有效果、有回報(bào)的無(wú)錫營(yíng)銷(xiāo)推廣。創(chuàng)新互聯(lián)建站專(zhuān)業(yè)成都網(wǎng)站建設(shè)十年了,客戶(hù)滿(mǎn)意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶(hù)聯(lián)系。

  • 案例描述
  • 問(wèn)題引出
  • 處理方案
  • 原理分析

一、案例描述

首先介紹三個(gè)類(lèi),為了便于理解將代碼省去非關(guān)鍵部分。

  • PrepCommonResp 是一個(gè)通用響應(yīng)類(lèi),為了支持多種返回類(lèi)型,設(shè)置了其中一個(gè)屬性result為泛型。
  •   
      
      
    1. public class PrepCommonResp { 
    2.  private T result; //獲取調(diào)用返回值 
    3.  private String code = "000000"; //獲取錯(cuò)誤碼 
    4.  private String msg = "Success"; 
    5. //這里省略getter setter等 
  • LeaderboardResp 是一個(gè)Leaderboard接口響應(yīng)類(lèi),其中有一個(gè)屬性是一個(gè)List集合集合中的對(duì)象為L(zhǎng)eaderboardPojo
  •   
      
      
    1. public class LeaderboardResp implements Serializable { 
    2.  List leaderboardList; 
    3.  //這里省略getter setter等 
  • LeaderboardPojo 是一個(gè)實(shí)體類(lèi)
  •   
      
      
    1. public class LeaderboardPojo { 
    2. //基本屬性 

需求:將一個(gè)JSON字符串的String類(lèi)型數(shù)據(jù)解析到指定了泛型的通用響應(yīng)類(lèi)實(shí)例PrepCommonResp 對(duì)象中。

二、問(wèn)題引出

一開(kāi)始編寫(xiě)時(shí),采用了Jackson的ObjectMapper類(lèi)readValue方法來(lái)進(jìn)行解析,具體代碼如下。

 
 
 
  1. ObjectMapper mapper = new ObjectMapper(); 
  2. PrepCommonResp resp = mapper.readValue(result,PrepCommonResp.class); 

我們期待的結(jié)果是JSON字符串被正確解析,并且result屬性的值是以指定泛型LeaderboardResp的格式存儲(chǔ)。但是通過(guò)斷點(diǎn)之后我們發(fā)現(xiàn)result屬性的值是以L(fǎng)inkedHashMap的形式存儲(chǔ),與期望結(jié)果不符。

三、解決方案

在分析原因之前,先來(lái)說(shuō)說(shuō)解決方式。解決方式有多種,我們通過(guò)了嘗試對(duì)比了各種方案之后選擇了其中一種較為簡(jiǎn)便的就是采用Gson的fromJson方法來(lái)解決,具體代碼如下:

 
 
 
  1. //嘗試使用Gson 
  2. Gson gson = new Gson(); 
  3. PrepCommonResp resp = gson.fromJson(result, new TypeToken>(){}.getType()); 
  4. List list = resp.getResult().getLeaderboardList(); 

運(yùn)行結(jié)果如下,result的值以我們期望的LeaderboardResp形式存儲(chǔ)

四、原理分析

1. 先理解泛型與編譯器虛擬機(jī)的關(guān)系以及什么是擦除?

解析: Java語(yǔ)言的泛型基本上是在編譯器中實(shí)現(xiàn)的。由編譯器執(zhí)行類(lèi)型檢測(cè)和推斷后生成普通的非泛型的字節(jié),虛擬機(jī)是完全無(wú)感知泛型存在的,這種實(shí)現(xiàn)技術(shù)稱(chēng)為擦除。編譯器使用泛型類(lèi)型信息保證類(lèi)型安全,然后在生成字節(jié)碼之前將其清除。

2. 為什么使用Jackson的readValue方法解析JSON字符串后result的屬性值會(huì)是LinkedHashMap而不是我們指定的LeaderboardResp呢?

解析:泛型只在編譯期間起到檢測(cè)作用,當(dāng)編譯器將泛型類(lèi)編譯完成之后,泛型類(lèi)的類(lèi)型參數(shù)都被全部擦除。接下來(lái)在運(yùn)行期間虛擬機(jī)并不知道泛型的存在,當(dāng)對(duì)JSON字符串進(jìn)行解析時(shí)由于泛型被擦除了導(dǎo)致虛擬機(jī)并不知道要將其解析成哪種類(lèi)型,所以就解析為了默認(rèn)的LinkedHashMap類(lèi)型,導(dǎo)致出現(xiàn)了上面的場(chǎng)景。

3. 那Gson是如何解決泛型擦除這種情況呢?

我們來(lái)看看這一句核心代碼

 
 
 
  1. PrepCommonResp resp = gson.fromJson(result, new TypeToken>(){}.getType()); 

解析:Gson的做法非常巧妙,如上面的代碼所示,將需要獲取類(lèi)型的泛型類(lèi)作為T(mén)ypeToken的泛型參數(shù)構(gòu)造一個(gè)匿名的子類(lèi),然后通過(guò)getType()方法就可以獲取到我們想要的泛型類(lèi)的泛型參數(shù)類(lèi)型??梢岳斫鉃槭菍⒎盒皖?lèi)型存起來(lái),解決了泛型擦除的問(wèn)題。

五、最后

感謝您的閱讀,如果喜歡本文歡迎關(guān)注和轉(zhuǎn)發(fā),本頭條號(hào)將持續(xù)分享IT技術(shù)知識(shí)。對(duì)于文章內(nèi)容有其他想法或意見(jiàn)建議等,歡迎提出共同討論共同進(jìn)步。如果您對(duì)于此場(chǎng)景有更好的解決方案也歡迎提出討論。


當(dāng)前名稱(chēng):當(dāng)JSON解析遇上了泛型,該如何處理泛型擦除問(wèn)題
網(wǎng)站地址:http://www.dlmjj.cn/article/dpieogh.html