涉及泛型的Gson轉化實體類

使用Gson轉化成實體類中的一個方法,傳的參數是 Type 對象。

fromJson(String json, Type typeOfT)

關於獲取Type對象,我知道的有兩種:

Type type = new TypeToken<T>() {}.getType();

Type type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

一開始在一個抽象類中,通過反射的方法獲取Type對象,實體類用泛型代替,然後將該抽象類作爲參數,傳入具體的實體類。

注意,這裏不能用第一種獲取Type對象的方法,否則會報類型強轉異常。

com.google.gson.internal.LinkedTreeMap cannot be cast to Basebean


使用第二種獲取Type對象方法,具體代碼:

public abstract class RequestCallback<T> extends Callback<T> {

    public RequestCallback(){
    }

    public T parseNetworkResponse(Response response, int i) throws Exception {

        String string = response.body().string();

        Type type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

       
        return new Gson().fromJson(string, type);
    }

}
Api.imQueryGroups(imsCookie, userId, new RequestCallback<BaseBean<List<GroupItemBean>>>() {

 @Override
 public void onError(Call call, Exception e, int i) {
 }
 @Override
 public void onResponse(BaseBean<List<GroupItemBean>> baseBean, int i) {

 }

});

這樣就能在使用網絡請求時,返回我們想要的實體類結果了。



PS:

如果對parseNetworkResponse()方法返回的實體具體化,就不會出現問題。就不需要創建一個子類去繼承Callback了。

Api.imQueryGroups(imsCookie, userId, new Callback<BaseBean<List<GroupItemBean>>>() {
                    @Override
                    public BaseBean<List<GroupItemBean>> parseNetworkResponse(Response response, int i) throws Exception {
                        Type type = new TypeToken<BaseBean<List<GroupItemBean>>>() {}.getType();
                        return new Gson().fromJson(response.body().string(), type);
                    }

                    @Override
                    public void onError(Call call, Exception e, int i) {
                    }

                    @Override
                    public void onResponse(BaseBean<List<GroupItemBean>> baseBean, int i) {
                    }
                });

但是這樣的話,每次獲取服務器返回的數據,都得寫一遍Gson的實體類轉化。做重複的事情是多麼的無意義啊,於是我決定另尋辦法。

網上找了好久都沒解決方法,但是搜到了“泛型擦除”,結合自身問題,我覺得很可能就出現在這裏。

泛型擦除:編譯時,泛型類型會改爲Object。

那麼,第一種方法獲取到的泛型是Object,Gson無法轉化成相對應的實體類報錯。



最後改用了第二種獲取Type對象的方法,這種方法沒有使用到泛型,最終編譯成功,數據解析也正常。


參考:

http://blog.csdn.net/gengv/article/details/5178055

https://www.cnblogs.com/baiqiantao/p/7475477.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章