Leo's Blog

Gson 泛型封装

前言: 在《Gson正确使用姿势(一)》的 Gson 泛型使用一节中介绍了如何使用泛型来简化POJO的设计,但是每次都要写 new TypeToken<XXX>(){};, 你能忍么? 我不能。。。本文主要介绍如何去将泛型的使用封装起来。

数据格式

还是使用项目中的json数据格式

1
2
3
4
5
6
7
{
"message":{
"code":"0"
"message":"success"
},
"data":{}
}
1
2
3
4
5
6
7
{
"message":{
"code":"0"
"message":"success"
},
"data":[]
}

方法原型

1
2
3
4
// 处理 data 为 Object 的情况
public static <T> Result<T> fromJsonObject(Reader reader,Class<T> class){}
// 处理 data 为 array 的情况
public static <T> Result<List<T>> fromJsonArray(Reader reader,Class<T> clazz){}

封装步骤

封装最重要的就是获取我们需要Type,使用 java 提供的 ParameterizedType 接口

实现一个简易的ParameterizedType

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;}
}

生成Gson 需要的泛型

解析data是Object的情况

1
2
3
4
public static <T> Result<T> fromJsonObject(Reader reader,Class<T> clazz){
Type type = new ParameterizedTypeImpl(Result.class,new Class[]{clazz});
return Gson.fromJson(reader,type);
}

解析data是array的情况

1
2
3
4
5
6
7
public static <T> Result<List<T>> fromJsonArray(Reader reader, Class<T> clazz){
// 生成 List<T> 的 type
Type listType = new ParameterizedTypeImpl(List.class,new Class[]{class});
// 生成 Result<List<T>> 的 type
Type type = new ParameterizedTypeImpl(Result.class,new Type[]{listTYpe});
return Gson.fromJson(reader,type);
}