• Android之基于Gson的ParameterizedType进行泛型解析


    创建GsonResponsePasare解析类,
    class GsonResponsePasare<T> {
    T deal(String response) {
    Type gsonType = new TypeToken<CommonResponse<T>>() {
    }.getType();
    CommonResponse<T> commonResponse = new Gson().fromJson(response, gsonType);
    lg.e("Data is : " + commonResponse.data, "Class Type is : " + commonResponse.data.getClass().toString());
    return commonResponse.data;
    }
    }
    创建CommonResponse解析实体,并以泛型定义data数据结构
    class CommonResponse<T> {
    int status;
    T data;
    }

    1.解析基本数据类型

    String strResult = new GsonResponsePasare<String>().deal("{"status":-4,"data":"xiaoxuan948"}");
    lg.e("StringResult:" + strResult);
    debug结果如下,


    2.解析自定义对象(失败过程分析)

    给出自定义对象的定义
    class DataInfo {
    String name;
    }

    单个对象解析过程

    DataInfo dataInfoResult = new GsonResponsePasare<DataInfo>().deal("{"status":-4,"data":{"name":"xiaoxuan948"}}");
    lg.e("DataInfo:" + dataInfoResult.toString(), "Value:" + dataInfoResult.name);
    debug结果如下,

    分析可知,commonResponse.data的数据类型并非期望的DataInfo类型,而是LinkedTreeMap类型,此处会提示强转异常。

    集合对象解析过程

    List<DataInfo> resultList = new GsonResponsePasare<List<DataInfo>>().deal("{"status":-4,"data":[{"name":"xiaoxuan948"},{"name":"coca"}]}");
    for (DataInfo entity : resultList) {
    lg.e("DataInfo:" + entity.toString(), "Value:" + entity.name);
    }
    debug结果如下,

    与解析单个对象类似,data子集的数据类型为LinkedTreeMap,非期望的DataInfo类型。


    解决方案

    class GsonResponsePasare<T> implements ParameterizedType {
    private final UtilsLog lg = UtilsLog.getLogger(GsonResponsePasare.class);

    public T deal(String response) {
    // Type gsonType = new ParameterizedType() {//...};//不建议该方式,推荐采用GsonResponsePasare实现ParameterizedType.因为getActualTypeArguments这里涉及获取GsonResponsePasare的泛型集合
    Type gsonType = this;

    CommonResponse<T> commonResponse = new Gson().fromJson(response, gsonType);
    lg.e("Data is : " + commonResponse.data, "Class Type is : " + commonResponse.data.getClass().toString());
    return commonResponse.data;
    }

    @Override
    public Type[] getActualTypeArguments() {
    Class clz = this.getClass();
    //这里必须注意在外面使用new GsonResponsePasare<GsonResponsePasare.DataInfo>(){};实例化时必须带上{},否则获取到的superclass为Object
    Type superclass = clz.getGenericSuperclass(); //getGenericSuperclass()获得带有泛型的父类
    if (superclass instanceof Class) {
    throw new RuntimeException("Missing type parameter.");
    }
    ParameterizedType parameterized = (ParameterizedType) superclass;
    return parameterized.getActualTypeArguments();
    }

    @Override
    public Type getOwnerType() {
    return null;
    }

    @Override
    public Type getRawType() {
    return CommonResponse.class;
    }
    }
    调用代码如下:
    List<DataInfo> resultList = new GsonResponsePasare<List<DataInfo>>() {
    }.deal("{"status":-4,"data":[{"name":"xiaoxuan948"},{"name":"coca"}]}");
    for (DataInfo entity : resultList) {
    lg.e("DataInfo:" + entity.toString(), "Value:" + entity.name);
    }

    GsonResponsePasare<DataInfo> pasare = new GsonResponsePasare<DataInfo>() {
    };
    DataInfo dataInfoResult = pasare.deal("{"status":-4,"data":{"name":"xiaoxuan948"}}");
    lg.e("DataInfo:" + dataInfoResult.toString(), "Value:" + dataInfoResult.name);

    注:
    1.直接采用new GsonResponsePasare<GsonResponsePasare.DataInfo>(){};方式解析json数据时,务必不要忽略最后的{}部分。
    2.CommonResponse若为内部类,必须申明为static类型,否则会提示
    java.lang.IllegalArgumentException
    at com.google.gson.internal.$Gson$Preconditions.checkArgument($Gson$Preconditions.java:46)
    at com.google.gson.internal.$Gson$Types$ParameterizedTypeImpl.<init>($Gson$Types.java:448)
    at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:103)
    at com.google.gson.reflect.TypeToken.<init>(TypeToken.java:72)
    at com.google.gson.reflect.TypeToken.get(TypeToken.java:296)
    at com.google.gson.Gson.fromJson(Gson.java:877)
    at com.google.gson.Gson.fromJson(Gson.java:844)
    at com.google.gson.Gson.fromJson(Gson.java:793)...








  • 相关阅读:
    samtools flags 分解
    epollo
    springaop 执行顺序问题
    java解析String类型的xml
    服务器调用服务器接口之间的抓包
    windows下mysql忘了安装时的root密码
    docker+jenkins+gitlab自动化构建
    influxdb基本操作
    记一次CPU过高排查过程
    dockercompose部署一个可远程连接的容器
  • 原文地址:https://www.cnblogs.com/linux007/p/5785046.html
Copyright © 2020-2023  润新知