对象流
对象流
ObjectOutputStream :ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。
ObjectInputStream:ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象。
ObjectOutputStream / ObjectInputStream
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串的功能
- 增强了读写对象的功能
- readObject() 从流中读取一个对象
- writeObject(Object obj) 向流中写入一个对象
使用流传输对象的过程称为序列化、反序列化
ObjectOutputStream
小案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package com.iopractise; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; /** * 使用ObjectOutputStream实现对象的序列化 */ public class Demo08 { public static void main(String[] args) throws IOException { //1.创建对象流 FileOutputStream fos = new FileOutputStream( "d:\\stu.bin" ); ObjectOutputStream oos = new ObjectOutputStream(fos); //2.序列化(写入操作) Student stu1 = new Student( "张三" , 20 ); oos.writeObject(stu1); //3.关闭 oos.close(); System.out.println( "序列化完毕" ); /** * 如果student类没有实现Serializable会报没有序列化异常 * java.io.NotSerializableException */ } } |
运行完毕之后,我们打开D盘下的stu.bin文件之后,会看到序列化之后的对象信息。(只不过是乱码的)
ͭ sr _x0016_com.iopractise.Student2"«?
I ageL namet _x0012_Ljava/lang/String;xp t 张三
ObjectInputStream
小案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.iopractise; import java.io.*; /** * 使用ObjectInputStream实现对象的反序列化(读取重构成对象) */ public class Demo09 { public static void main(String[] args) throws IOException, ClassNotFoundException { //1.创建对象流 FileInputStream fis = new FileInputStream( "d:\\stu.bin" ); ObjectInputStream ois = new ObjectInputStream(fis); //2.序列化(写入操作) Student student = (Student) ois.readObject(); //3.关闭 ois.close(); System.out.println( "反序列化完毕" ); System.out.println(student.toString()); } } |
运行结果:
序列化完毕
Student{name='张三', age=20}
注意:
(1)如果 Student student = (Student) ois.readObject(); Student student2 = (Student) ois.readObject();连续读两次会抛出异常:java.io.EOFException,表示已经读完了,就不能再读了。
(2)如果实体类中又套用了其他的实体类,那么在序列化和反序列化的时候,这个套用的实体类也要实现Serializable,接口否则是会抛异常的。
(3)private static final long serialVersionUID = 1L;//这个值可以随便指定 这个序列化id表示的是序列化的类和反序列化的类是同一个类。这个时候,我们在执行反反序列化的类。会抛出异常:local class incompatible: stream classdesc serialVersionUID = 3603863914098147085, local class serialVersionUID = 1
解决办法也挺简单的,我们再重新执行一下序列化的类,然后再执行反序列化的类,也就是说重新序列化一次就好了。
(4)private transient int age;//如果我们对于那些不想序列化和反序列化的属性,我们可以使用transient 关键字进行修饰。transient 表示瞬时的,暂时的,如果能够序列化或者反序列化,那不就成了永久的了吗。
再次运行结果:序列化完毕
Student{name='张三', age=0};//可见age就没有被序列化。
(5)静态属性也是不能序列化或者反序列化的。比如;private static String country="中国";
(6)序列化多个对象的时候,可以借助集合来进行实现。
补充:(序列化多个对象的时候)
第一种实现方式:
//2.序列化(写入操作)
Student stu1 = new Student("张三", 20);
Student stu2 = new Student("李四", 25);
oos.writeObject(stu1);
oos.writeObject(stu2);
//2.反序列化(写入操作)
Student student = (Student) ois.readObject();
Student studen2 = (Student) ois.readObject();
//3.关闭
ois.close();
System.out.println("序列化完毕");
System.out.println(student.toString());
System.out.println(studen2.toString());
第二种实现方式:通过集合的方式实现:
//2.序列化(写入操作)
Student stu1 = new Student("张三", 20);
Student stu2 = new Student("李四", 25);
ArrayList<Student> stuList = new ArrayList<Student>();
stuList.add(stu1);
stuList.add(stu2);
oos.writeObject(stuList);
//3.关闭
oos.close();
System.out.println("序列化完毕");
//2.反序列化(写入操作)
ArrayList<Student> stuList = (ArrayList<Student>) ois.readObject();
//3.关闭
ois.close();
System.out.println("序列化完毕");
System.out.println(stuList.toString());
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY