真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

關(guān)于Gson的TypeToken-創(chuàng)新互聯(lián)

文章目錄
    • 引言
    • Type是什么
    • 獲取類型的困惑
    • 自定義TypeToken
    • 解決問題
    • 總結(jié)

創(chuàng)新互聯(lián)公司基于成都重慶香港及美國等地區(qū)分布式IDC機房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)服務(wù)器托管報價,主機托管價格性價比高,為金融證券行業(yè)服務(wù)器機柜租賃,ai人工智能服務(wù)器托管提供bgp線路100M獨享,G口帶寬及機柜租用的專業(yè)成都idc公司。
引言

Gson在Json解析中使用廣泛, 常用的數(shù)據(jù)類型都可以解析, 特殊的可以自定義Adapter解析. 在解析大量具有某些相同結(jié)構(gòu)的數(shù)據(jù)上,我們總想復(fù)用已有的類型, 為了復(fù)用通??梢允褂美^承和泛型. 比如服務(wù)端返回的json都有類似結(jié)構(gòu):

{"code":200,
    "message":"success",
    "data":"{...}"
}

其中data對應(yīng)的結(jié)構(gòu)不定, 一種考慮是使用泛型:

public class Response{public T data;//簡化數(shù)據(jù), 省略了其他字段
}

于是在做json解析是很可能會這樣使用:

String json = "{\"data\":\"data from server\"}";
Type type = new TypeToken>(){}.getType();
Responseresult = new Gson().fromJson(json, type);

這個TypeToken是如何和類型Response產(chǎn)生關(guān)系,又是怎樣存儲泛型信息的? 首先需要明確Type是什么.

Type是什么

這里的Type指java.lang.reflect.Type, 是Java中所有類型的公共高級接口, 代表了Java中的所有類型. Type體系中類型的包括:數(shù)組類型(GenericArrayType)、參數(shù)化類型(ParameterizedType)、類型變量(TypeVariable)、通配符類型(WildcardType)、原始類型(Class)、基本類型(Class), 以上這些類型都實現(xiàn)Type接口.

參數(shù)化類型,就是我們平常所用到的泛型List、Map;

數(shù)組類型,并不是我們工作中所使用的數(shù)組String[] 、byte[],而是帶有泛型的數(shù)組,即T[] ;

通配符類型, 指的是,等等

原始類型, 不僅僅包含我們平常所指的類,還包括枚舉、數(shù)組、注解等;

基本類型, 也就是我們所說的java的基本類型,即int,float,double等

本文的重點在于參數(shù)化類型(ParameterizedType).

public interface ParameterizedType extends Type {// 返回確切的泛型參數(shù), 如Map返回[String, Integer]
    Type[] getActualTypeArguments();
    
    //返回當前class或interface聲明的類型, 如List返回List
    Type getRawType();
    
    //返回所屬類型. 如,當前類型為O.I, 則返回O. 頂級類型將返回null 
    Type getOwnerType();
}
獲取類型的困惑

對于普通的類想要獲取類型簡單調(diào)用.class或者getClass()方法即可,

ClassstringClass = String.class;
ClassstringClass2 = "hello".getClass();

但對于泛型你不能這樣做,

Response.class //不能通過編譯
Response.class //只能這樣獲取類型, 但無法知道元素的類型

那么在做json解析時我們?nèi)绻_實是需要讓Gson解析成Response, 可以像上文的方式處理.

自定義TypeToken

先看一段代碼:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract class MyTypeToken{private final Type type;
    public MyTypeToken() {Type genericSuperclass = getClass().getGenericSuperclass();
        if(genericSuperclass instanceof Class){throw new RuntimeException("Missing type parameter.");
        }
        ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
        Type[] typeArguments = parameterizedType.getActualTypeArguments();
        type = typeArguments[0];
    }

    public Type getType() {return type;
    }
}
  1. MyTypeToken聲明為抽象類, 使用時需要對其進行實例化, 實例化過程可以分解如下:

    MyTypeTokensToken = new MyTypeToken(){};

    相當于

    class MyTypeToken$0 extends MyTypeToken{}
    MyTypeTokensToken = new MyTypeToken$0();
    

    這樣分解的目的在于明確sToken的類型是MyTypeToken$0(匿名的),父類型是MyTypeToken而不是MyTypeToken.

  2. getClass().getSuperclass()獲取的是當前對象所屬的類型的父類型. 注意到抽象類實例化時需要給具體的泛型類, 如果沒有提供則使用Object(但此時使用的已不是泛型類了, 而是原始類型, 也就是擦除泛型后的類型)代替泛型參數(shù). 因此如果像上面那樣實例化, 那么getClass().getGenericSuperclass()得到的將是類型參數(shù)實例化后的父類型MyTypeToken, 泛型信息保留下來了. 如果不用泛型得到的是MyTypeToken, 是原始類型.

  3. 得到泛型參數(shù)實例化后的類型,getActualTypeArguments()返回的是確切的類型參數(shù)數(shù)組, 此處MyTypeToken只有一個類型參數(shù), 返回的是數(shù)組[String.class].

至此, 通過new MyTypeToken>() {}.getType()得到的正是表示Response的類型, 將該類型應(yīng)用在Gson在解析Response上將獲得和TypeToken一致的效果(當然就這么點代碼功能肯定是比不上了).

解決問題

探究TypeToken的目的其實為了解決以下問題而總結(jié)的.

//封裝getType()操作
public class TokenUtil{public staticType getType(){return new MyTypeToken() {}.getType();
    }
}
// 本意在于獲取Response的類型, 但是new MyTypeToken() {}時已經(jīng)實現(xiàn)了
// 抽象類, 相當于創(chuàng)建一個子類 class MyTypeToken$0extends MyTypeToken{},
// 實例化時雖然傳入的是Response, 但.getGenericSuperclass()=MyTypeToken$0// 于是getType()返回的只是泛型參數(shù)類型E, 正真解析是按照Gson流程選擇Map或者List
Type type = TokenUtil.>getType();
// fromJson返回Map或者List, ClassCastException!
Responseo = new Gson().fromJson(json, type);
總結(jié)

Gson解析時TypeToken的泛型參數(shù)只能使用時傳入確切的類型才能獲取正確的Type, 這也是TypeToken設(shè)計成抽象類的巧妙之處和原因(改為只有protected構(gòu)造方法的普通類原理一樣). 一旦將TypeToken改成普通類, 根據(jù)上面的分析, 一切類型信息都被擦除, Gson解析將得不到預(yù)期的類型.

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


當前標題:關(guān)于Gson的TypeToken-創(chuàng)新互聯(lián)
本文地址:http://weahome.cn/article/dpecdi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部