序列化
序列化的两大难题:循环依赖与深度嵌套
序列化中解决循环依赖的核心办法:
- 切断循环:在引用到达形成环之前,将其设置为 null 或不序列化该字段(如使用
transient关键字)。 - 使用ID替代对象:不直接序列化整个对象,而是序列化其唯一标识符(如ID)。反序列化后,再通过ID在上下文中查找并重建引用关系。
- 自定义序列化:通过实现
writeObject/readObject等方法,手动控制哪些引用需要被写入或如何重建,从而避免循环。 - 改变数据结构:从根本上重新设计类之间的关系,用非循环的结构(如树形、层级)替代双向引用。
- 使用第三方库:某些序列化库(如 Kryo、FST)通过引用处理机制,本身就能支持循环引用。
深度嵌套的原因:
对象图过于复杂,引用链过长,导致序列化时递归过深,最终触发栈溢出错误。
核心解决办法:
- 改变数据结构:从根本上重构模型,打破深度关联。使用扁平化结构或通过ID关联来替代直接的对象嵌套。
- 自定义序列化过程:手动控制序列化深度。在递归到达安全阈值前,停止序列化深层对象,改为序列化其标识符。
- 使用迭代替代递归:在自定义序列化逻辑中,使用栈或队列等数据结构以迭代方式遍历对象图,避免程序调用栈的溢出。
- 选用非递归序列化库:采用专门处理复杂对象图的序列化框架,它们内部使用迭代而非递归,从而不受栈深度限制。
浙公网安备 33010602011771号