搞懂fastjson 对泛型的反序列化原理

359 阅读2分钟

“持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

fastjson 是现在非常常用的一个json 的序列化和反序列化工具,是阿里发布的,虽然最近一直在暴雷,各种漏洞,但是这不影响我们学习他。

fastjson的使用

加入依赖

在pom.xml中直接增加fastjson的依赖就行了,向下面这样

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.75</version>
</dependency>

常规使用

public static void main(String[] args) {
    TreeNode treeNode = new TreeNode(10);
        //转为字符串
    String jsonStr = JSON.toJSONString(treeNode);
        // 字符串转为对象
    TreeNode treeNode1 = JSON.parseObject(jsonStr, TreeNode.class);
    System.out.println();
}

泛型的使用

看下我们常用的反序列化

List<TreeNode>  list = JSON.parseObject("",new TypeReference<List<TreeNode>>(){});

先解释下: TypeReference 是一个泛型类,持有了当前的类型

这里的泛型的反序列化,到底是如何实现的呐? 到底在运行时怎么知道需要序列化的泛型是什么呐? 今天学习下知识点,也是今天主要想记录的。

源码

想懂原理还得扒源码,看懂了也没什么神奇了

知识点1 匿名类

new TypeReference<List>(){} 这行代码就是创建一个匿名类,等价于创建一个类实现TypeReference ,然后进行实例化。 千万不要迷糊,因为平常的时候我们一般是对接口使用,比如 Runnable,不熟悉的话可以复习下

知识点2 重点

直接点进去TypeReference 这个类,可以看到下面的构造函数

protected TypeReference(){
    Type superClass = getClass().getGenericSuperclass();
    // 这里是重点,看样子可以获取到泛型的信息
    Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];

    Type cachedType = classTypeCache.get(type);
    if (cachedType == null) {
        classTypeCache.putIfAbsent(type, type);
        cachedType = classTypeCache.get(type);
    }

    this.type = cachedType;
}

Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; 这个函数开发中是极少使用,即使作为老司机我也没有用过这个函数,你用过吗?

这句一定要记住,也是泛型的实现最重要的方式,一定是superclass,还做了一次强转。然后转为自己要用的类型 注意这里

总结

最后总结下,fastjson的泛型的反序列化底层原理就是根据type 进行反序列化, 知识点就是 匿名类 和 getActualTypeArguments 最后留个作业,你可以模拟一个这样的场景,如果你在开发中需要在运行时知道泛型的类型, 可以使用这种方法