GSON TypeToken 解决泛型问题
Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除的问题解决 在开发时,遇到了下面这条语句,不懂,然习之。private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhuiHaoDetailModel>(); Gson gson=new Gson(); JSONObject object=new JSONObject(callbackValue); listLottery = gson.fromJson(object.getString("lists"), new TypeToken<List<MyZhuiHaoDetailModel>>() { }.getType());GSON提供了 TypeToken 这个类来帮助我们捕获(capture)像List<MyZhuiHaoDetailModel>这样的泛型信息。上文创建了一个匿名内部类,这样,Java编译器就会把泛型信息编译到这个匿名内部类里,然后在运行时就可以被 getType()方法用反射API提取到。 下面来看看gson的反序列化,Gson提供了fromJson()方法来实现从Json相关对象到java实体的方法。 在日常应用中,我们一般都会碰到两种情况,转成单一实体对象和转换成对象列表或者其他结构。 先来看第一种: 比如json字符串为:{"name":"name0","age":0} 代码: Person person = gson.fromJson(str, Person.class);提供两个参数,分别是json字符串以及需要转换对象的类型。 第二种,转换成列表类型: 代码:
List<Person> ps = gson.fromJson(str, new TypeToken<List<Person>>(){}.getType()); for(int i = 0; i < ps.size() ; i++) { Person p = ps.get(i); System.out.println(p.toString()); }可以看到上面的代码使用了TypeToken,它是gson提供的数据类型转换器,可以支持各种数据集合类型转换。 经过比较,gson和其他现有java json类库最大的不同是gson需要序列化的实体类不需要使用annotation来标识需要序列化得字段,同时gson又可以通过使用annotation来灵活配置需要序列化的字段。 另外,java反射包中的TypeToken类是用来解决java运行时泛型类型被擦除的问题的,有点不好理解,我们通过一个例子来认识什么是泛型的运行时类型擦除。
ArrayList<String> stringList = Lists.newArrayList(); ArrayList<Integer> intList = Lists.newArrayList(); System.out.println("intList type is " + intList.getClass()); System.out.println("stringList type is " + stringList.getClass()); System.out.println(stringList.getClass().isAssignableFrom(intList.getClass()));上面的代码我们声明了两个泛型的ArrayList类型,一个泛型的类型参数是String,另外一个是Integer;然后我们输出了两个泛型的Class,并输出两个list的类型是否是同一个list。我们看下输出的结果:intList type is class java.util.ArrayListstringList type is class java.util.ArrayListtrue前两个输出都是java.util.ArrayList,而第三个输出竟然是true,也就是认为stringList和intList的类型是一样的。这就是所谓的泛型类型擦除。运行时我们不知道泛型类型的类型参数是什么了。TypeToken可以解决这个问题,请看下面代码: TypeToken<ArrayList<String>> typeToken = new TypeToken<ArrayList<String>>() {}; TypeToken<?> genericTypeToken = typeToken.resolveType(ArrayList.class.getTypeParameters()[0]); System.out.println(genericTypeToken.getType());注意上面第一行代码使用了一个空的匿名类。第二行使用了resolveType方法解析出泛型类型,第三行代码打印出泛型类型,输出是:class java.lang.String可以看出TypeToken解析出了泛型参数的具体类型。TypeToken的方法列表如下:方法 描述getType() 获得包装的java.lang.reflect.Type.getRawType() 返回大家熟知的运行时类getSubtype(Class<?>) 返回那些有特定原始类的子类型。举个例子,如果这有一个Iterable并且参数是List.class,那么返回将是List。getSupertype(Class<?>) 产生这个类型的超类,这个超类是指定的原始类型。举个例子,如果这是一个Set并且参数是Iterable.class,结果将会是Iterable。isAssignableFrom(type) 如果这个类型是 assignable from 指定的类型,并且考虑泛型参数,返回true。List<? extends Number>是assignable from List,但List没有.getTypes() 返回一个Set,包含了这个所有接口,子类和类是这个类型的类。返回的Set同样提供了classes()和interfaces()方法允许你只浏览超类和接口类。isArray() 检查某个类型是不是数组,甚至是<? extends A[]>。getComponentType() 返回组件类型数组。 Gson的基本使用就是这么多,至于annotation方面可以参考gson的官方文档,希望能对初学java和gson的同学有所帮助。
GSON TypeToken 解决泛型问题的更多相关文章
- Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题
在开发时,遇到了下面这条语句,不懂,然习之. private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhu ...
- Gson通过借助TypeToken获取泛型参数的类型的方法
最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下. 由于Java泛型的实现机制,使 ...
- Gson通过借助TypeToken获取泛型参数的类型的方法(转)
最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下. 由于Java泛型的实现机制,使 ...
- 代码混淆 GSON完满解决
头疼的问题,json使用了google的gson三方包,可是混淆的时候出了问题 明明已经按照gson的官方文档,把混淆脚本加上去了,却还是出问题. 今天同事找到一篇博客,关于这个问题的: 我们是将js ...
- 使用Gson轻松解决复杂结构的Json数据解析
转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50961803 JSON简介 JSON(JavaScript Object Notati ...
- [转]用GSON 五招之内搞定任何JSON数组
关于GSON的入门级使用,这里就不提了,如有需要可以看这篇博文 <Google Gson的使用方法,实现Json结构的相互转换> ,写的很好,通俗易懂. 我为什么写这篇文章呢?因为前几晚跟 ...
- Gson基本操作,JsonObject,JsonArray,String,JavaBean,List互转
(转自)https://www.cnblogs.com/robbinluobo/p/7217387.html String.JsonObject.JavaBean 互相转换 User user = n ...
- [转] Android:用GSON 五招之内搞定任何JSON数组
[From] http://www.open-open.com/lib/view/open1472632967912.html 写在前面 关于GSON的入门级使用,这里就不提了,如有需要可以看这篇博文 ...
- 使用GSON和泛型解析约定格式的JSON串(转)
时间紧张,先记一笔,后续优化与完善. 解决的问题: 使用GSON和泛型解析约定格式的JSON串. 背景介绍: 1.使用GSON来进行JSON串与java代码的互相转换. 2.JSON的格式如下三种: ...
随机推荐
- 内存管理——linux内核学习
买了<深入Linux内核架构>这本书准备了解一下linux内核机制.但是最开始看了十几页感觉看着很累,本来都准备弃了 过了段时间看见一个面经有linux内核的内容,于是就照着那个先把内存管 ...
- hdu 5641 BestCoder Round #75
King's Phone Accepts: 310 Submissions: 2980 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- IDE、SDK、API
IDE 集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器.编译器.调试器和图形用户界面等工具.集成了代 ...
- Map value类型不同的写法
Map value类型不同的写法 Map<String, Object> accountMap=new HashMap<String, Object>(); int userI ...
- JSON.NET的Self referencing loop detected with type的原因以及解决办法
模型中有循环引用是很常见的.例如,以下模型显示双向导航属性: : public class Category : { : public Category() : { : Products = new ...
- sqlserver 查询 inner join 同一表2次 只出一条查询结果
inner join T_MTN_MobileNumber k on 1=1 and k.hddm='01' inner join (select a.hdxx+','+b.hdxx as hdxx ...
- QRCode.js:使用 JavaScript 生成二维码
什么是 QRCode.js? QRCode.js 是一个用于生成二维码的 JavaScript 库.主要是通过获取 DOM 的标签,再通过 HTML5 Canvas 绘制而成,不依赖任何库. 基本用法 ...
- Redis设置Key的过期时间 – EXPIRE命令
EXPIRE key seconds 为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除. 操作key对生存时间的影响 生存时间可以通过使用 DEL 命令来删除整个 ...
- javascript装饰器模式
装饰器模式 什么是装饰器 原名decorator 被翻译为装饰器 可以理解为装饰 修饰 包装等意 现实中的作用 一间房子通过装饰可以变得更华丽,功能更多 类似一部手机可以单独使用 但是很多人都愿意家个 ...
- ubuntu14.04+sublime3+latex配置
目的:用题目所说的三个东西写论文. 配置方法:参考 http://blog.csdn.net/bleedingfight/article/details/72810606, 但该博客所提的texliv ...