Java 进阶 (四)Java 反射 TypeToken 解决泛型运行时类型擦除问题
在开发时,遇到了下面这条语句,不懂,然习之。
GSON
提供了 TypeToken
这个类来帮助我们捕获(capture)像List<MyZhuiHaoDetailModel>
这样的泛型信息。上文创建了一个匿名内部类,这样,Java 编译器就会把泛型信息编译到这个匿名内部类里,然后在运行时就可以被 getType()
方法用反射 API 提取到。
下面来看看 gson 的反序列化,Gson
提供了fromJson()
方法来实现从 Json 相关对象到 java 实体的方法。
在日常应用中,我们一般都会碰到两种情况,转成单一实体对象和转换成对象列表或者其他结构。
先来看第一种:
比如 json 字符串为:{"name":"name0","age":0}
代码:
提供两个参数,分别是 json 字符串以及需要转换对象的类型。
第二种,转换成列表类型:
代码:
可以看到上面的代码使用了 TypeToken,它是 gson 提供的数据类型转换器,可以支持各种数据集合类型转换。
经过比较,gson 和其他现有 java json 类库最大的不同是 gson 需要序列化的实体类不需要使用 annotation 来标识需要序列化得字段,同时 gson 又可以通过使用 annotation 来灵活配置需要序列化的字段。
另外,java 反射包中的 TypeToken 类是用来解决 java 运行时泛型类型被擦除的问题的,有点不好理解,我们通过一个例子来认识什么是泛型的运行时类型擦除。
上面的代码我们声明了两个泛型的 ArrayList 类型,一个泛型的类型参数是 String,另外一个是 Integer;然后我们输出了两个泛型的 Class,并输出两个 list 的类型是否是同一个 list。我们看下输出的结果:
前两个输出都是 java.util.ArrayList,而第三个输出竟然是 true,也就是认为 stringList 和 intList 的类型是一样的。这就是所谓的泛型类型擦除。运行时我们不知道泛型类型的类型参数是什么了。
TypeToken 可以解决这个问题,请看下面代码:
注意上面第一行代码使用了一个空的匿名类。第二行使用了 resolveType 方法解析出泛型类型,第三行代码打印出泛型类型,输出是:
可以看出 TypeToken 解析出了泛型参数的具体类型。
TypeToken 的方法列表如下:
Gson 的基本使用就是这么多,至于 annotation 方面可以参考 gson 的官方文档,希望能对初学 java 和 gson 的同学有所帮助。
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/9178819fbff1cfce1b0dae3ae】。文章转载请联系作者。
评论