使用Gson解析泛型类型
2016-05-21 22:56
513 查看
在程序中访问网络的时候返回的Json有时候是固定的形式,我们所需要的json信息是以嵌套的形式给出的,比如
User info:
Book info:
如果我们直接用Gson解析的话,要有对应的实体类才行,比如要解析上面的两个Json的话,就要有两个类
另外还需要UserInfo和BookInfo两个类:
这样的话每个Json都要对应两个类,很繁琐,另外如果Json比较多的话,会产生很多类,而这些类有一半都是多余的,维护起来也很麻烦。
观察UserInfoBean和BookInfoBean两个类,可以发现这两个类中的成员变量除了json_msg字段的类型不一样,其他的都完全一样,如果能把这连个类统一成一个类的话就能解决类多余的问题。Java的泛型恰好可以解决这个问题。上面的连个类用泛型可以写为:
此时,UserInfoBean和BookInfoBean两个类就可以写成InfoBean和InfoBean,不管有多上类都可以写成这种形式。
试着我们常用的Gson用法去去解析json,
上面的代码并不能运行,原因是InfoBean是泛型,并不能直接获取class类型。通过android studio的代码提示功能可以看到Gson的fromJson()方法解析String类型的json有两种:
第一个方法就是我们一般常用的,接受class类型, 第二个方法接受一个Type类型,Type类型一般与与泛型的类型推断有关,查阅这个方法的文档可以发现这个方法就是用来处理泛型类型的,文档中介绍需要用TypeToken来获取泛型的type类型,并且给出了具体的用法:
按照上面的形式现在我们来处理InfoBean:
现在就可以正确的获取userInfo对象了。
另外,一般情况下,在json对应的实体类中,类的成员变量的名字要和json对应字段的名字一样才能正确解析,比如上面的User info的json中的”result_code”字段在InfoBean类中要有result_code成员变量来对应。而我们在开发安卓程序的时候一般习惯用驼峰命名法,即result_code字段一般习惯用resultCode来命名。
注解中的名字对应json中的字段名字,这时我们就可以对实体类中的成员变量随便命名了。对InfoBean加上注解后:
这样我们在代码中访问json实体类的时候,代码的阅读性就会提高很多。
User info:
{ "result_code":"4000", "result_msg":"接受数据正常", "json_msg":{ "user_name":"jack", "user_age":15 } }
Book info:
{ "result_code":"4000", "result_msg":"接受数据正常", "json_msg":{ "book_name":"Java编程思想", "book_price":"108.00" } }
如果我们直接用Gson解析的话,要有对应的实体类才行,比如要解析上面的两个Json的话,就要有两个类
public class UsreInfoBean { public String result_code; public String result_msg; public UserInfo json_msg; } public class BookInfoBean { public String result_code; public String result_msg; public BookInfo json_msg; }
另外还需要UserInfo和BookInfo两个类:
public class UserInfo { public String user_name; public int user_age; } public class BookInfo{ public String book_name; public String book_price; }
这样的话每个Json都要对应两个类,很繁琐,另外如果Json比较多的话,会产生很多类,而这些类有一半都是多余的,维护起来也很麻烦。
观察UserInfoBean和BookInfoBean两个类,可以发现这两个类中的成员变量除了json_msg字段的类型不一样,其他的都完全一样,如果能把这连个类统一成一个类的话就能解决类多余的问题。Java的泛型恰好可以解决这个问题。上面的连个类用泛型可以写为:
public class InfoBean<T> { public String result_code; public String result_msg; public T json_msg; }
此时,UserInfoBean和BookInfoBean两个类就可以写成InfoBean和InfoBean,不管有多上类都可以写成这种形式。
试着我们常用的Gson用法去去解析json,
String json = ...; //对应上面的User info的json //下面代码在android studio中会报错 InfoBean<UserInfo> userInfo = new Gson().fromJson(json, InfoBean<UserInfo>.class);
上面的代码并不能运行,原因是InfoBean是泛型,并不能直接获取class类型。通过android studio的代码提示功能可以看到Gson的fromJson()方法解析String类型的json有两种:
Object fromJson(Sting, Class<Object>) Object fromJson(String, Type)
第一个方法就是我们一般常用的,接受class类型, 第二个方法接受一个Type类型,Type类型一般与与泛型的类型推断有关,查阅这个方法的文档可以发现这个方法就是用来处理泛型类型的,文档中介绍需要用TypeToken来获取泛型的type类型,并且给出了具体的用法:
Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
按照上面的形式现在我们来处理InfoBean:
String json = ...; //对应上面的User info的json Type type = new TypeToken<InfoBean<UserInfo>>(){}.getType(); InfoBean<UserInfo> userInfo = new Gson.fromJson(json, type);
现在就可以正确的获取userInfo对象了。
另外,一般情况下,在json对应的实体类中,类的成员变量的名字要和json对应字段的名字一样才能正确解析,比如上面的User info的json中的”result_code”字段在InfoBean类中要有result_code成员变量来对应。而我们在开发安卓程序的时候一般习惯用驼峰命名法,即result_code字段一般习惯用resultCode来命名。
Gson对这种情况也是有处理的,只要使用一个注解就可以解决问题:
@SerializedName("result_code")
注解中的名字对应json中的字段名字,这时我们就可以对实体类中的成员变量随便命名了。对InfoBean加上注解后:
public class InfoBean<T> { @SerializedName("result_code") public String resultCode; @SerializedName("result_msg") public String resultMsg; @SerializedName("json_msg") public T resultObj; }
这样我们在代码中访问json实体类的时候,代码的阅读性就会提高很多。
相关文章推荐
- jackson、Gson反序列化 泛型
- Gson.toJson()时内存溢出StackOverflowError
- JAVA泛型—— 3fe8 转
- JAVA泛型详解——转
- 编写高质量代码改善C#程序――使用泛型集合代替非泛型集合(建议20)
- 简单学习C#中的泛型方法使用
- C#通过反射创建自定义泛型
- C#泛型用法实例分析
- C语言泛型编程实例教程
- C# 泛型的简单理解(安全、集合、方法、约束、继承)分享
- C#泛型Dictionary的用法实例详解
- C#泛型和反射实例解析
- C#泛型实例详解
- .NET开发基础:从简单的例子理解泛型 分享
- RadioButtonList绑定图片及泛型Dictionary应用
- Swift编程中的泛型解析
- C#实现利用泛型将DataSet转为Model的方法
- 关于C#泛型列表List<T>的基本用法总结
- 详解C#中的泛型以及编程中使用泛型的优点
- list泛型自定义排序示例