Java集合序列化需集合及所有元素均实现Serializable,用ObjectOutputStream一次性写入整体;LinkedList因内部Node transient应避免使用;须声明serialVersionUID并用transient保护敏感字段。

Java 中集合对象的序列化,核心是确保整个集合及其所有元素都满足可序列化要求,再用 ObjectOutputStream 一次性写入——不是遍历逐个序列化,而是把集合本身当作一个整体对象来处理。
集合本身必须可序列化,且元素类型全部实现 Serializable
ArrayList、HashSet、LinkedHashSet、TreeSet 等 JDK 常见集合类已实现 Serializable 接口,可以直接序列化。但前提是:集合中每个元素(包括嵌套对象、泛型实际类型)都必须实现 Serializable;否则运行时抛 NotSerializableException。
- 例如
List<User>要成功序列化,User类必须声明implements Serializable - 若
User中包含Date、String、自定义实体等字段,这些类型也得可序列化(JDK 大部分基础类已支持) -
特别注意:
LinkedList虽然也实现了Serializable,但其内部Node类在 JDK 8+ 中被标记为transient且未公开实现序列化,反序列化后内容为空——实践中应避免直接序列化LinkedList,优先选用ArrayList或ArrayDeque
正确声明 serialVersionUID 并处理敏感字段
不显式声明 serialVersionUID 会导致类结构稍作修改(如增删字段)后反序列化失败,报 InvalidClassException。同时,密码、令牌等不应落盘的字段需用 transient 修饰。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在集合元素类中添加:
private static final long serialVersionUID = 1L;(建议用 IDE 自动生成更安全的值) - 敏感字段如
private transient String token;,序列化时自动跳过 - 含函数式接口字段(如
Comparator<T>、lambda 表达式)时,也应加transient,并在readObject中手动重建
用 ObjectOutputStream 一行完成批量写入
无需 for 循环,直接调用 writeObject() 写入整个集合引用即可。文件为二进制格式,不可读但高效紧凑。
立即学习“Java免费学习笔记(深入)”;
- 示例代码:
oos.writeObject(userList); // userList 是 ArrayList<User> 实例
}
- 注意捕获
IOException;关闭流推荐使用 try-with-resources 自动释放 - 生成的
.dat文件不能用文本编辑器查看,但体积小、序列化/反序列化速度快
反序列化要强转并注意泛型擦除
ObjectInputStream.readObject() 返回的是 Object 类型,需按原始类型强转。由于 Java 泛型擦除,运行时无法得知具体泛型参数,所以转换依赖写入时的实际类型。
- 示例:
List<User> loaded = (List<User>) ois.readObject();
}
- 必须捕获
ClassNotFoundException(类未在 classpath 中)和IOException - 若类结构变更(如字段重命名、删除),反序列化可能失败,此时需调整
serialVersionUID或自定义readObject - 跨语言、需可读性或长期兼容场景,建议改用 Jackson 序列化为 JSON(
mapper.writeValue(new File("data.json"), list))

















