【从零开始学Java | 第三十八篇】序列化流(Object Stream)

张开发
2026/4/18 0:24:25 15 分钟阅读

分享文章

【从零开始学Java | 第三十八篇】序列化流(Object Stream)
目录前言一、什么是序列化与反序列化二、序列化流与反序列化流1.序列化流的方法2.反序列化流的方法3.准备一个可序列化的类4.序列化5.反序列化三、一些细节1.对类添加一个属性2.某个属性不想序列化到本地文件总结前言在前面的 Java I/O 系列博客中我们学会了如何使用字节流拷贝文件也学会了如何使用字符流按行读取文本。但是在实际开发中我们经常会遇到一种更高级的需求我想把内存里活生生的 Java 对象比如一个带有用户名、密码、等级的User对象直接保存到硬盘上或者通过网络发送给另一台电脑该怎么做你当然可以自己把对象的属性拼接成字符串比如张三,18,VIP写进文件读取时再自己切割字符串还原。但这种做法太低效也太容易出错了。Java 为此提供了一套终极解决方案对象序列化流。一、什么是序列化与反序列化序列化 (Serialization)把内存中的 Java 对象转换成一串字节序列二进制数据的过程。反序列化 (Deserialization)把硬盘上或网络接收到的字节序列重新恢复成内存中的 Java 对象的过程。在 Java 中完成这项魔法的两个核心处理流包装流是ObjectOutputStream对象输出流用于序列化写出ObjectInputStream对象输入流用于反序列化读取二、序列化流与反序列化流1.序列化流的方法构造方法说明public ObjectOutputStream(OutputStream out)把基本流包装成高级流成员方法说明public final void writeObject(Object obj)将对象序列化写到文件2.反序列化流的方法构造方法说明public ObjectIutputStream(IutputStream out)把基本流包装成高级流成员方法说明public final void readObject(Object obj)把序列化到本地文件中的对象读取到程序中3.准备一个可序列化的类如果你想让一个类的对象支持序列化这个类必须实现java.io.Serializable接口。我们可以看到Serializable接口是没有任何方法的因此该接口只是一个标记型接口用来标记一个类可以用来序列化的。4.序列化public class Test { public static void main(String[] args) throws IOException { ObjectOutputStream oos new ObjectOutputStream(new FileOutputStream(src\\c.txt)); Student s1 new Student(zhangsan, 23); oos.writeObject(s1); oos.close(); } }运行结果5.反序列化public class Test2 { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectInputStream ois new ObjectInputStream(new FileInputStream(src\\c.txt)); Object o ois.readObject(); System.out.println(o); ois.close(); } }运行结果三、一些细节1.对类添加一个属性当我们以旧类的形式以序列化形式写出到硬盘后如果我们对类添加了一个新的属性值之后再对之前写出的文件进行读入会有什么反应呢展示①我们首先对学生类在原有基础上添加了一个地址属性。②读取旧属性序列化数据。可以看到序列化使用了序列化版本值来标记类的如果我们新添加了一个属性这个版本值就会改变.那么我们是不是可以把我们自己的类固定一个版本值这样java在反序列化的时候就不会出现版本值不同的情况了呢此时读取时就不会出错了2.某个属性不想序列化到本地文件有一些隐私属性如果我不想序列化到本地文件应该怎么做我们可以对该属性添加一个“transient”关键字。这样写出的数据就不会把地址值写到硬盘中因此读入也不会将该属性读入。总结序列化流与反序列化流有三个很重要的细节如果你想让一个类能够进行序列化写出要让类实现Serializable接口版本号危机与 serialVersionUID使用 transient 保护敏感信息

更多文章