Gson字符串数组转成List对象(含泛型操作)
通常情况下,Server端返回的json数据应该可以一次性完全解析,但是要是遇到server返回的json里又包含json字符串就得自己再手动解析一次了。
我们知道json字符串解析成模型类型很简单,但是如果要把json数组字符串解析List对象,应该怎么办呢?
举一个实际的例子:
"name": "zhaoxa", "score": 100 "name": "zhaoxa2", "score": 76 "name": "zhaoxa3", "score": 99 "name": "zhaoxa4", "score": 48根据这个json字符串列表,我们设计名为Student的数据模型,Parcelable接口可以使用AS插件一键生成:
public class Student implements Parcelable{
String name;
int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
public String getName() {
return name;
public void setName(String name) {
this.name = name;
public int getScore() {
return score;
public void setScore(int score) {
this.score = score;
@Override
public int describeContents() {
return 0;
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
dest.writeInt(this.score);
protected Student(Parcel in) {
this.name = in.readString();
this.score = in.readInt();
public static final Creator<Student> CREATOR = new Creator<Student>() {
@Override
public Student createFromParcel(Parcel source) {
return new Student(source);
@Override
public Student[] newArray(int size) {
return new Student[size];
现在开始着手解析这个json数组字符串。
1. 先转成数组,再转成List
最常规的方法把jsonString转化为T[]数组,然后再使用Arrys.asList将数组转为List。
Student[] array = new Gson().fromJson(jsonString,Student[].class);
List<Student> list = Arrays.asList(array);
Log.i("lxc"," ---> " + list);
通过断点,可以看到list下面的数据已经转为Student类型了。
public <T> List<T> parseString2List(String json) {
Type type = new TypeToken<List<T>>(){}.getType();
List<T> list = new Gson().fromJson(jsonString,type);
return list;
嗯,没有报错,我们运行时断点看看list里的数据类型。
我们通过这句话调用方法:
List<Student> list = parseString2List(jsonString);
可以看到,list中的数据类型不是Student
,而是LinkedTreeMap
,LinkedTreeMap
是Gson库内部数据模型,换句话说我们的解析失败了,尝试着将parseString2List
方法中的泛型T
去掉,运行结果一样,说明Gson解析时不支持泛型。
真的就没有办法了么,难道解析数组json必须得重复调用相似的代码?嗯,在接触ParameterizedType
接口之前,你应该很难实现这个功能。但是现在知道了ParameterizedType
接口,我们就有了第三次尝试。
第三次尝试
public <T> List<T> parseString2List(String json,Class clazz) {
Type type = new ParameterizedTypeImpl(clazz);
List<T> list = new Gson().fromJson(json, type);
return list;
private class ParameterizedTypeImpl implements ParameterizedType {
Class clazz;
public ParameterizedTypeImpl(Class clz) {
clazz = clz;
@Override
public Type[] getActualTypeArguments() {
return new Type[]{clazz};
@Override
public Type getRawType() {
return List.class;
@Override
public Type getOwnerType() {
return null;
在调用的地方使用:
List<Student> list = parseString2List(jsonString, Student.class);
List<Book> list2 = parseString2List(jsonString, Book.class);
断点查看解析结果,嗯,完美解析~
好的,现在在回过头来看看,ParameterizedType的几个方法的含义吧,以HashMap<String,Integer>为例。
getActualTypeArguments 返回实际类型组成的数据,即new Type[]{String.class,Integer.class}
getRawType 返回原生类型,即 HashMap
getOwnerType 返回 Type 对象,表示此类型是其成员之一的类型。例如,如果此类型为 O<T>.I<S>
,则返回 O<T>
的表示形式。 如果此类型为顶层类型,则返回 null。这里就直接返回null就行了。
<div align ="right">写于 9/7/2017 4:52:27 PM</div>