千家信息网

fastJson中怎么反序列化处理泛型

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,fastJson中怎么反序列化处理泛型,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。都会的json解析在我们日常的编码工
千家信息网最后更新 2026年11月03日fastJson中怎么反序列化处理泛型

fastJson中怎么反序列化处理泛型,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

都会的json解析

在我们日常的编码工作中,常常会制定或者遇到这样的json结构

{  "resultcode": "200",  "reason": "成功的返回",  "result": {    "area": "浙江省温州市平阳县",    "sex": "男",    "birthday": "1989年03月08日"  }}

对于该接口的提供者,最外层的resultcode reason和result 这三个元素都是有的。因此我们可以定义一个这样的Response类

public class Response {    private String resultcode;    private String reason;    private T result;}

使用泛型来决定result最终向里面填充什么东西。当然,这里所填充的是一个对象,姑且我们也可以将它定义为User类

public class User {    private String area;    private String sex;    private String birthday;}

这样,我们的数据就可以按照示例json的约定规则,返回给调用者了。 而作为调用方,也就是接收这条数据的机器,我们则需要定义如下的类ResopnseUser

public class ResopnseUser {    private String resultcode;    private String reason;    private User result;}public class User {    private String area;    private String sex;    private String birthday;}

然后我们可以使用fastJson来进行愉快的解析了

        String  testJson = "{\"resultcode\":\"200\",\"reason\":\"成功的返回\",\"result\":{\"area\":\"浙江省温州市平阳县\",\"sex\":\"男\",\"birthday\":\"1989年03月08日\"}}";        ResponseUser response1 =  JSONObject.parseObject(testJson,ResponseUser.class);

可以看到,也确实得到了我们想要的结果

思考改进措施

但是,这有个不太严重的后果。我每跟提供者对接一个接口,就得生成一个与之对应的类。久而久之,这些专用的类会变得越来越多,嵌套也会越来越深。既然提供者可以抽象出一个Response类,那么我是否也可以向提供者那样处理?

        String  testJson = "{\"resultcode\":\"200\",\"reason\":\"成功的返回\",\"result\":{\"area\":\"浙江省温州市平阳县\",\"sex\":\"男\",\"birthday\":\"1989年03月08日\"}}";        Response response =  JSONObject.parseObject(testJson,Response.class);

很遗憾,我们得到的结果并非所期望的,只有最外层的数据解析成功了,内层的result仍是JSONObject.

求助于万能的论坛

幸运的事,在这万千工程师中并非只有想到了这种处理办法,并且已经有人解决这类问题了! 通过各种搜索下来,我们发现了fastJson提供了TypeReference这个类,可以解决我们的问题。

String  testJson = "{\"resultcode\":\"200\",\"reason\":\"成功的返回\",\"result\":{\"area\":\"浙江省温州市平阳县\",\"sex\":\"男\",\"birthday\":\"1989年03月08日\"}}";        Response response =  JSONObject.parseObject(testJson,new TypeReference>(){});

很好,我们已经得到了想要的结果,终于可以统一所有的接口最外层返回值的判断了。

绝不止步于此

等等,就没有发现什么问题吗?泛型在编译时会执行类型擦除啊!这也就是我们第一次直接使用Response response = JSONObject.parseObject(testJson,Response.class);时无效的原因。 那么,即使我们这么写了new TypeReference>(){}不也一样会被擦除掉吗?运行时它是如何获取到我们所定义的实际类型的? 通过查看TypeReference的源码,幸运的是该源码十分的简单而且代码量少。首先进入的就是它的构造函数protected TypeReference(),通过debug我们发现,在代码执行到第二行时,就已经获得了我们所写的泛型.

        Type superClass = getClass().getGenericSuperclass();        Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];

这段代码很简单,获取到它的父类getGenericSuperclass()就获取到了实际的类型.继续跟进代码,我们可以发现它调用了一个native方法private native String getGenericSignature0();获取到了该类和父类的一些信息ClassRepository和Type。 此时,回过头来我们再看new TypeReference>(){}其实是创建了一个TypeReference的匿名内部类,通过该类的getGenericSuperclass(),获取到了实际的类型信息。

继续深挖

让我们现在回顾一下我们的所得,注要有2点:

  1. 泛型在编译时会执行类型擦除。

  2. 获取到它的父类getGenericSuperclass()就获取到了实际的类型。 等等,这两点是互相矛盾的啊。1说没有,2又说还能找到,到底是怎么回事呢?通过查看编译后的字节码文件,我们找到了答案。

这是包含代码Response response = JSONObject.parseObject(testJson,new TypeReference>(){});的方法的class文件反编译后的信息。我们可以看到 它多了一个LocalvariableTypeTable,里面的Signature正好存储了实际的类型信息。**也就是说类型并未完全擦除,我们依然可以通过反射的方式拿到参数的类型。**所谓的擦除,只是把方法 code 属性的字节码进行擦除。 另外,我们还看到了InnerClasses列表中,有一个内部类,叫Main$1,也就是我们的这个new TypeReference>(){}

总结

  1. 可以通过JSONObject.parseObject(testJson,new TypeReference>(){});的方式,解决json中嵌套泛型的问题。方便、快捷、直观

  2. 可以通过getClass().getGenericSuperclass();获取到真实类型。验证代码

  // 这类创建了一个HashMap的匿名子类        HashMap subIntMap = new HashMap(){};        System.out.println(subIntMap.getClass().getSuperclass());        Type subClassType = subIntMap.getClass().getGenericSuperclass();        if(subClassType instanceof ParameterizedType){            ParameterizedType p = (ParameterizedType) subClassType;            for (Type t : p.getActualTypeArguments()){                System.out.println(t);            }        }

输出结果

class java.util.HashMapclass java.lang.Stringclass java.lang.Integer
  1. 类型并未完全擦除,可以通过反射的方式拿到参数的类型。验证代码

 ResponseUser response = new ResponseUser();        Field field = response.getClass().getField("result");        System.out.println("result Type is "+ field.getType());        System.out.println("result GenericType is "+ field.getGenericType());public class ResponseUser {    private String resultcode;    private String reason;    public List result;}

输出结果

result Type is interface java.util.Listresult GenericType is java.util.List

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

类型 代码 成功 实际 结果 也就是 信息 可以通过 提供者 问题 平阳 平阳县 浙江 浙江省 温州 温州市 编译 处理 外层 接口 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 精品咖啡豆 上海挚品互联网科技有限公司 新华互联网科技 北京路客互联网科技有限公司 期待互联网科技 深圳天众互联网科技公司 互联网科技汛 上海亿帐通互联网科技 互联网科技大会案例 北京华百购互联网科技有限公司 互联网科技大奖都有哪些公司 企晟互联网信息科技有限公司 互联网科技和法律行业 互联网在线教育科技创业 卓翼科技产业互联网合作 广东工业互联网大赛深圳学泰科技 互联网科技接地气 版纳互联网科技选哪家 广州三三互联网科技有限公司 重庆科技产业互联网有哪些 卓越科技互联网 招聘 互联网科技博主是什么意思 深圳育鹏互联网科技有限公司招聘 河南住房之家互联网科技 佛山市翊博互联网络科技有限公司 翼展科技 首家互联网医院 中科明德北京互联网科技 上海科技产业互联网平台 神州科技互联网有限公司 福仕德教育科技互联网
0