IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> fastjson出现$ref问题解析,重复引用问题 -> 正文阅读

[游戏开发]fastjson出现$ref问题解析,重复引用问题

现象

最近在调试接口的时候,发现fastjson输出到前端页面的字符串带了一些奇怪的字符,比如$ref

分析原因

这其实是由于对象的重复引用导致的。因为fastjson在做序列化的时候,会把已经序列化过的对象存到一个map中保存起来。所以在每次进行序列化的时候都会去缓冲查找是否已经序列化过该对象,如果发现有序列化过该对象,就不会进行序列化了,而是返回它的一个引用
$ref。

引用标识
“$ref”:..” 上一级
“$ref”:”@” 当前对象,也就是自引用
“$ref”:”$” 根对象
{"$ref":"../.."} 引用父对象的父对象
“$ref”:”$.children.0” 基于路径的引用,相当于root.getChildren().get(0)
// 这是其中的一个源码片段
    public boolean writeReference(JSONSerializer serializer, Object object, int fieldFeatures) {
        SerialContext context = serializer.context;
        int mask = SerializerFeature.DisableCircularReferenceDetect.mask;
        if (context == null || (context.features & mask) != 0 || (fieldFeatures & mask) != 0) {
            return false;
        }
		// 检查引用缓存
        if (serializer.references != null && serializer.references.containsKey(object)) {
            serializer.writeReference(object);
            return true;
        } else {
            return false;
        }
    }

案例复现

	import com.alibaba.fastjson.JSONObject;
    public static void main(String[] args) {
        Car car1 = new Car(999,"bwm");
        List<Car> list1 =new  ArrayList();
            list1.add(car1);
        JSONObject cars = new JSONObject();
        cars.put("list1",list1);
        cars.put("list2",list1);
        cars.put("list3",list1);
        System.out.println(cars.toJSONString());
    }
// 控制台输出结果
Connected to the target VM, address: '127.0.0.1:56012', transport: 'socket'
{"list1":[{"brand":"bwm","price":999}],"list3":[{"$ref":"$.list1[0]"}],"list2":[{"$ref":"$.list1[0]"}]}
Disconnected from the target VM, address: '127.0.0.1:56012', transport: 'socket'
Process finished with exit code 0

解决方法

1,当jsonObject的value是一个集合时,不要重复添加集合中的源码,这会导致一个重复引用问题;所以建议在重复引用时,对对象采用深拷贝,把拷贝对象添加到不同的集合中;

2,在构建jsonobject的时候,可以禁用探测重复引用的功能,但这可能会导致一个严重的问题,overstack;

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 12:08:57  更:2022-04-26 12:10:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/17 0:03:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码