如何使用 ObjectOutputStream 实现对象的序列化并保存到磁盘文件

小丽大大_8541

小丽大大_8541

2026-04-15

533人浏览

原创

ObjectOutputStream序列化对象前必须确保类实现Serializable接口并显式定义serialVersionUID,使用try-with-resources关闭流,多个对象写入需避免复用同一实例或调用reset()。

如何使用 objectoutputstream 实现对象的序列化并保存到磁盘文件

ObjectOutputStream 序列化对象前必须确保类可序列化

Java 中 ObjectOutputStream 只能序列化实现了 Serializable 接口的类,否则运行时抛出 java.io.NotSerializableException。这不是编译错误,容易漏掉检查。

  • 在目标类声明后加上 implements Serializable
  • 强烈建议显式定义 private static final long serialVersionUID = 1L;,否则 JVM 自动生成的值依赖类结构(字段增删、重排序都会导致反序列化失败)
  • 被标记为 transient 的字段不会被序列化,需自行处理逻辑
  • 内部类(尤其是匿名或局部类)默认持有外部类引用,若外部类不可序列化,会连带失败;优先用静态内部类

写入文件时必须配合 FileOutputStream 和 try-with-resources

ObjectOutputStream 本身不负责文件 I/O,它只做序列化编码;必须套在 FileOutputStream 上。直接 new ObjectOutputStream(new FileOutputStream("a.dat")) 是常见写法,但要注意资源释放和异常嵌套。

  • 务必用 try-with-resources,因为 ObjectOutputStream 的 close() 会刷新缓冲区并写入终止标记(stream header),漏掉会导致后续读取报 StreamCorruptedException
  • 不要在 ObjectOutputStream 外层再套一层 BufferedOutputStream——它不必要,且可能干扰 header 写入顺序
  • 文件路径建议用 Paths.get(...).toFile() 或 new File(...) 显式构造,避免硬编码斜杠方向问题

示例:

Livestream Script Generator
Livestream Script Generator

直播带货脚本:话术、节奏、互动、促单。适用于主播、电商运营、MCN机构。

下载
try (FileOutputStream fos = new FileOutputStream("user.dat");
     ObjectOutputStream oos = new ObjectOutputStream(fos)) {
    oos.writeObject(new User("Alice", 28));
}

多次写入同一 ObjectOutputStream 实例会引发 StreamCorruptedException

这是最常踩的坑:想循环保存多个对象,却反复调用同一个 ObjectOutputStream 的 writeObject() —— 它会在每次写入前重复写入 stream header,破坏格式。

  • 如果要追加写入多个对象,有两种安全方式:
    – 每次新建 ObjectOutputStream(注意:header 会重复,读取端需用 ObjectInputStream 循环 read,忽略 header 异常)
    – 更推荐:一次性收集对象到 List,再整体 writeObject(list)
  • 若坚持复用流,必须调用 oos.reset() 清除已写入的 handle 缓存(用于处理对象引用),但 header 仍只写一次,适用于单个流写多个独立对象的场景
  • 注意:reset() 后,之前写过的相同对象实例会被当新对象处理(不再复用引用),可能影响反序列化后的对象图结构

反序列化时 ClassLoader 和类版本必须匹配

用 ObjectInputStream 读取时,JVM 需要加载对应类,并校验 serialVersionUID。哪怕只是改了方法体、加了注释,只要 serialVersionUID 不变,就能兼容;反之,即使只动了一个字段名,没改 serialVersionUID,也会失败。

  • 确保反序列化时类在 classpath 中,且与序列化时是同一份字节码(IDE 编译缓存、热部署、模块隔离都可能导致“类存在但不等价”)
  • 如果类结构已变更(如删字段),可自定义 readObject() 方法,在其中手动处理缺失字段的默认值
  • 生产环境慎用 Java 原生序列化——它耦合紧、无跨语言能力、有安全风险(反序列化任意类可能触发恶意代码),优先考虑 JSON(Jackson/Gson)或 Protocol Buffers

实际写磁盘时,真正关键的是三件事:类标 Serializable、流必须正确关闭、多个对象别误用单一流实例。其他细节大多围绕这三点展开。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

stream

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

12077

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

9162

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7832

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1284

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

1028

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1516

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

3169

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20411

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1375

8

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CentOS 官方文档
CentOS 官方文档

共0课时 | 0人学习

极客学院Java8新特性视频教程
极客学院Java8新特性视频教程

共17课时 | 4.3万人学习