前言
本文记录普通非泛型对象和泛型对象在反序列化过程中的区别:
在实际开发过程中,我们经常需要将复杂的数据结构序列化为字符串存储或在网络间传输,同时也需要能够从字符串反序列化回原始数据结构;
基于上述情况,由此引出如下问题:在反序列过程中的泛型擦除
一、什么是泛型擦除?
在Java中,泛型是在编译时期被类型擦除的特性。这意味着编译后的字节码并不包含泛型信息,而是使用原始类型(即没有泛型限定的类型)。这种机制是为了保持向后兼容性和简化JVM的设计。由于类型擦除的存在,运行时的类型系统无法直接识别泛型类型的具体信息,这在使用反射或序列化/反序列化时会带来一定的挑战。
二、泛型擦除的影响
当使用FastJSON或其他序列化框架时,如果涉及到泛型类型,比如HashMap<String, List>,那么在序列化过程中,这些泛型信息会丢失。具体来说,FastJSON在序列化时,它只能看到HashMap和List的基本类型,而无法知道具体的键值类型(String)和列表中的元素类型(XXXObject)
三、不需要考虑泛型擦除的情况
对于非泛型类型的对象,例如一个普通的Java类,如XXXObject.class,其类型信息在编译后不会被擦除。因此,在序列化和反序列化过程中,FastJSON可以直接读取和写出这些对象的属性,不需要额外的信息来确定它们的类型
四、对map对象使用FastJSON进行反序列
当使用FastJSON反序列化一个表示HashMap<String, List>的JSON字符串时,由于类型擦除,FastJSON无法直接知道应该创建什么样的泛型实例。为了解决这个问题,需要显式地告诉FastJSON期望的类型是什么,因此需要使用TypeReference来指定具体的泛型类型
如何使用TypeReference,代码示例如下
HashMap<String, List<XXXObject>> data = JSON.parseObject(jsonString,
new TypeReference<HashMap<String, List<XXXObject>>>(){});
这里的TypeReference就是一个匿名类实例,它告诉FastJSON期望得到的是HashMap<String, List>类型的对象。
总结
- 对于非泛型类型:FastJSON可以直接读取和写出这些对象的属性,因为它们的类型信息在编译后仍然存在。
- 对于泛型类型:由于类型擦除,FastJSON在序列化/反序列化时需要额外的帮助来确定泛型的具体类型。通常,这可以通过使用TypeReference或类似的机制来实现。