- 在序列化的时候,fastjson默认打开CircularReferenceDetect,这样在序列化的时候会检查循环依赖,如下代码:
ParentBean parentBean = new ParentBean();
parentBean.setName("father");
ChildBean childBean = new ChildBean();
childBean.setName("son");
//下面2句代码是关键
parentBean.setChildBean(childBean);
//先注释这句
// childBean.setParentBean(parentBean);
List<Object> dataList = new ArrayList<>();
dataList.add(parentBean);
dataList.add(childBean);
System.out.println(JSON.toJSONString(dataList));
System.out.println(JSON.toJSONString(dataList, SerializerFeature.DisableCircularReferenceDetect));
ParentBean
和ChildBean
相互持有对方引用。
上面代码中childBean先不设置parentBean,
打印结果
[{"childBean":{"name":"son"},"name":"father"},{"$ref":"$[0].childBean"}]
[{"childBean":{"name":"son"},"name":"father"},{"name":"son"}]
把注释打开,结果:
[{"childBean":{"name":"son","parentBean":{"$ref":".."}},"name":"father"},{"$ref":"$[0].childBean"}]
java.lang.StackOverflowError
at com.alibaba.fastjson.serializer.SerializeWriter.writeFieldValueStringWithDoubleQuoteCheck(SerializeWriter.java:1378)
第一个打印正常,第二个因为禁止循环引用检测,导致序列化栈溢出了。
Jackson的ObjectMapper也有这个问题,不过默认就会报错,相比之下还是fastjson更人性化一些,不过需要在反序列化的时候也要用fastjson,否则反序列化结果不是你想要的。
ObjectMapper解决循环引用方法https://stackoverflow.com/questions/37388613/jackson-serialize-entity-with-self-reference。
不建议对象循环引用,也不建议同时序列化parentBean和childBean,网络调用方很可能解析不了。
- fastjson在序列化时会丢失参数泛型,如方法参数是List<Long>,参数序列化后再反序列化变成了List<Integer>,自己根据ParameterizedType的rawType和actualTypeArgument来解析,配合递归。
网友评论