涉及泛型的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

猜你喜欢

转载自blog.csdn.net/xiadanxin/article/details/79483196