0

0

Java中的集合类如何实现序列化_Serializable接口与自定义处理

P粉602998670

P粉602998670

发布时间:2026-03-06 13:15:15

|

203人浏览过

|

来源于php中文网

原创

arraylist能直接序列化而linkedlist可能出问题,因其字段均实现serializable且无transient节点;linkedlist的node类包私有、未序列化且被标记transient,导致反序列化后元素丢失。

java中的集合类如何实现序列化_serializable接口与自定义处理

为什么 ArrayList 能直接序列化,而 LinkedList 却可能出问题?

因为 ArrayList 的字段全是可序列化的(Object[]size),JVM 默认序列化机制能完整还原;LinkedList 内部用双向链表节点 Node,而 JDK 8+ 中这个类是包私有的、未实现 Serializable,且被标记为 transient —— 所以默认序列化后反序列化会丢失全部元素。

  • 实操上,别依赖默认行为去序列化 LinkedList 或自定义集合,尤其在 RPC、缓存、日志落盘等场景
  • 如果必须用,优先替换成 ArrayListArrayDeque,它们序列化稳定、性能更好
  • 真要保留 LinkedList,得重写 writeObjectreadObject,手动遍历链表写入/重建节点

自定义集合类加 implements Serializable 就够了吗?

不够。加接口只是“声明支持”,真正起作用的是字段是否可序列化、是否有自定义序列化逻辑、以及是否规避了不可序列化引用。

  • 所有非 transientstatic 字段类型都必须可序列化,否则反序列化抛 java.io.NotSerializableException
  • ComparatorSupplier 等函数式接口字段时,记得用 transient + 自定义 readObject 重建,否则 lambda 表达式可能因捕获上下文导致序列化失败
  • 建议显式声明 private static final long serialVersionUID = 1L;,避免因类结构微调(比如加个字段)导致 InvalidClassException

writeObjectreadObject 怎么写才不踩坑?

这两个私有方法是 JVM 序列化协议的钩子,不是普通重载 —— 方法签名错一个字符(比如参数不是 ObjectOutputStream)就完全不会被调用,变成走默认逻辑。

通义灵码
通义灵码

阿里云出品的一款基于通义大模型的智能编码辅助工具,提供代码智能生成、研发智能问答能力

下载
  • 必须严格匹配签名:private void writeObject(ObjectOutputStream out) throws IOException
  • 开头一定要调 out.defaultWriteObject()(除非你彻底放弃父类/字段的默认序列化)
  • 反序列化时,readObject 里先调 in.defaultReadObject(),再按顺序读你手动写的字段,顺序错会导致数据错位
  • 别在 writeObject 里调 out.writeObject(this),会无限递归栈溢出

Externalizable 替代 Serializable 值不值得?

只在极少数场景划算:集合结构极其固定、字段极多、且对序列化体积/速度有硬性要求(比如高频网络传输的中间件)。日常开发基本不用。

立即学习Java免费学习笔记(深入)”;

  • Externalizable 要求你实现 writeExternal/readExternal,且必须手动处理所有字段,包括父类的 —— 没有 defaultWriteObject 这种兜底
  • 类升级时,新增字段不会自动跳过,旧版本反序列化新数据会直接抛 EOFException
  • 它绕过 serialVersionUID 校验,但代价是完全失去向后兼容弹性
序列化不是“加个接口就完事”的事情,最麻烦的永远是隐式依赖 —— 比如集合里塞了个没实现 Serializable 的业务对象,或者用了某个内部类作为泛型实参。上线前务必做一次真实反序列化测试,别只看 ObjectOutputStream 能写出去。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

181

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

225

2025.12.18

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

186

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

125

2025.11.27

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

214

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

192

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

60

2026.01.05

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1825

2023.10.19

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

19

2026.03.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.1万人学习

C# 教程
C# 教程

共94课时 | 10.7万人学习

Java 教程
Java 教程

共578课时 | 77.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号