Android开发不得不了解的Gson泛型封装

json格式

1.后台给的数据格式有两种:

// data 为 object 的情况
{"code":"0","msg":"message","success":"true","data":{}}
// data 为 array 的情况
{"code":"0","msg":"message","success":"true","data":[]}

2、假定第一种的对应的Java类型为 BaseBean<XXX> ,第二种为 BaseBean<List<XXX>> ,如果每一个数据都去生成一个Bean去进行解析,就十分繁琐,

而直接使用new TypeToken<XXX>(){}的形式来解析泛型,得到的数据却是LinkedTreeMap格式的数据,所以深入研究了一下Gson的泛型封装,终于可以直接拿到泛型的Bean数据了。

封装原型

// 处理 data 为 object 的情况
public static <T> BaseBean<T> fromJsonObject(String reader, Class<T> clazz) {}
// 处理 data 为 array 的情况
public static <T> BaseBean<List<T>> fromJsonArray(String reader, Class<T> clazz){}

 封装原理

TypeToken的作用是用于获取泛型的类,返回的类型为Type,真正的泛型信息就是放在这个Type里面。

Type是Java中所有类型的父接口,在1.8以前是一个空接口,自1.8起多了个getTypeName()方法,下面有ParameterizedTypeGenericArrayTypeWildcardTypeTypeVariable 几个接口,以及Class类。这几个接口在本次封装过程中只会用到 ParameterizedType ,所以简单说一下:

ParameterizedType 简单说来就是形如“ 类型<> ”的类型,如:Map<String,User>。下面就以 Map<String,User> 为例讲一下里面各个方法的作用。

public interface ParameterizedType extends Type {
     // 返回Map<String,User>里的String和User,所以这里返回[String.class,User.clas]
    Type[] getActualTypeArguments(); 
    // Map<String,User>里的Map,所以返回值是Map.class
    Type getRawType();
    // 用于这个泛型上中包含了内部类的情况,一般返回null
    Type getOwnerType(); 
}

 实现过程

 1、实现一个简易的 ParameterizedType

public class ParameterizedTypeImpl implements ParameterizedType {
    private final Class raw;
    private final Type[] args;
    public ParameterizedTypeImpl(Class raw, Type[] args) {
        this.raw = raw;
        this.args = args != null ? args : new Type[0];
    }
    @Override
    public Type[] getActualTypeArguments() {
        return args;
    }
    @Override
    public Type getRawType() {
        return raw;
    }
    @Override
    public Type getOwnerType() {return null;}
}

 

2、生成Gson需要的泛型

2.1解析data是object的情况

public static <T> BaseBean<T> fromJsonObject(String reader, Class<T> clazz) {
    Type type = new ParameterizedTypeImpl(BaseBean.class, new Class[]{clazz});
    return GSON.fromJson(reader, type);
}

2.2解析data是array的情况

public static <T> BaseBean<List<T>> fromJsonArray(String reader, Class<T> clazz) {
    // 生成List<T> 中的 List<T>
    Type listType = new ParameterizedTypeImpl(List.class, new Class[]{clazz});
    // 根据List<T>生成完整的Result<List<T>>
    Type type = new ParameterizedTypeImpl(BaseBean.class, new Type[]{listType});
    return GSON.fromJson(String , type);
}

举例

public static <T> BaseBean<List<T>> fromJsonArray(String reader, Class<T> clazz) {
    Type type = TypeBuilder
            .newInstance(BaseBean.class)
            .beginSubType(List.class)
            .addTypeParam(clazz)
            .endSubType()
            .build();
    return GSON.fromJson(reader, type);
}

public static <T> BaseBean<T> fromJsonObject(String reader, Class<T> clazz) {
    Type type = TypeBuilder
            .newInstance(BaseBean.class)
            .addTypeParam(clazz)
            .build();
    return GSON.fromJson(reader, type);
}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值