fastjson输出json字符串ref问题

最近在排查问题的时候,日志打印的采用对象的输出的方式是JSONObject.toJSONString(object)的方式,发现一个问题,会打印出 $ref的符号。最开始怀疑是框架的问题,后来查看了源码发现问题并没这么简单,这是fastjson库的一个特性。是为了节省打印空间也为了表示对象引用关系。


static class User {

        private String name;

        private Integer id;

        public User(String name, Integer id) {
            this.name = name;
            this.id = id;
        }

       // setter getter
    }

测试类:

        List<User> userList = new ArrayList<>();
        User user = new User("micro", 1);
        userList.add(user);
        userList.add(user);

        System.out.println(JSONObject.toJSONString(userList));

这里输出结果如下:

[{"id":1,"name":"micro"},{"$ref":"$[0]"}]

这里看源码分析:
根据传入的类型找到对应的ObjectSerializer,ListSerializer的输出关键实现如下:
在这里插入图片描述
会根据设置的SerializerFeature来确认数据的一些特点,disableCircularReferenceDetect是控制是否识别循环引用,默认是开启的,所以同一个引用会被输出为ref的形式。

System.out.println(JSONObject.toJSONString(userList, SerializerFeature.DisableCircularReferenceDetect));

这样即可输出:
[{“id”:1,“name”:“micro”},{“id”:1,“name”:“micro”}]
如果关闭它即可输出的堆的内容,但是这里就无法识别出不同的引用是否指向的同一个对象了。


个人建议还是保持默认的值,因为最近排查的问题就是发现一个对象数组在遍历的过程中去修改其引用的对象,当遍历结束的时候发现整个数组中所有引用的对象都变成了一个值,理论上应该是不同的值的,后来排查debug才发现虽然每个对象都保持自己的引用,但都是引用的同一个堆上的对象。导致最后一次修改会隐蔽的修改掉前面对象引用的对象值。这种问题十分难排查,如果输出了数组的日志,看到ref标志就知道他们之间的引用关系,迅速定位问题。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值