【Java-----IO流(八)之对象专属流详解】
创始人
2024-04-06 22:05:48
0

序列化和反序列化定义

  • 序列化:指把Java对象转换为字节序列的过程
  • 反序列化:指把字节序列恢复为Java对象的过程

序列化和反序列化的作用

  • 序列化:在传递和保护对象时,保证对象的完整性和可传递性,对象转换为有序字节流,以便在网络上传输或者保护在本地文件中
  • 反序列化:根据字节流中保护的对象状态及描述信息,通过反序列化重建对象

序列化和反序列化的实现

  • 对象序列化流:ObjectOutputStream
  • 对象反序列化流:ObjectInputStream

构造方法

  • ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
  • ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream

序列化对象和反序列化对象的方法

  • void writeObject(Object obj):将指定的对象写入ObjectOutputStream
  • Object readObject():从ObjectInputStream读取一个对象

Serializable接口

参与序列化和反序列化的对象,必须实现Serializable接口。否则会报错:Java.io.NotSerializableException

通过源代码发现,Serializable接口只是一个标志接口:

public interface Serializable{}

这个接口中什么代码都没有,它是起标识作用的,Java虚拟机看到这个类实现了这个接口,会为该类自动生成一个序列化版本号

序列化版本号的作用

Java语言中是采用什么机制来区分类的?

一:首先通过类名进行比较,如果类名不一样,肯定不是同一个类

二:如果类名一样,则需要靠序列化版本号进行区分

自动生成序列化版本号的缺点:一旦代码确定之后,不能进行后续的修改,因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候Java虚拟机会认为这是一个全新的类

结论:凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号,这样,以后这个类即使代码修改了,但是版本号不变,Java虚拟机会认为是同一个类。

例:

public class Student implements Serializable {//手动写出序列号private static final long serialVersionUID=1L;int age;String name;

对象序列化代码实现

对象类:

public class Student implements Serializable {int age;String name;public Student() {}public Student(int age,String name) {this.name=name;this.age=age;}public void setName(String name) {this.name=name;}public String getName() {return name;}public void setAge(int age) {this.age=age;}public int getAge() {return age;}public String toString() {return "Student{name="+name+","+"age="+age+"}";}
}

序列化:

public static void main(String[] args) throws IOException {//创建对象Student s=new Student(3,"Alice");//序列化FileOutputStream fos=new FileOutputStream("D:\\aaa\\student.txt");ObjectOutputStream oos=new ObjectOutputStream(fos);//序列化对象oos.writeObject(s);oos.flush();oos.close();
}

反序列化对象代码实现

反序列化:

//反序列化
FileInputStream fis=new FileInputStream("D:\\aaa\\student.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
//反序列化对象
Object obj=ois.readObject();
//输出对象
System.out.println(obj);
ois.close();
//输出:Student{name=Alice,age=3}

一次序列化和反序列化多个对象

序列化:

//创建集合存放对象
List studentList=new ArrayList();
//创建对象
Student s1=new Student(3,"Alice");
Student s2=new Student(5,"bob");
Student s3=new Student(2,"rose");
//将对象存入集合
studentList.add(s1);
studentList.add(s2);
studentList.add(s3);
//序列化
FileOutputStream fos=new FileOutputStream("D:\\aaa\\student.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
//序列化一个集合
oos.writeUnshared(studentList);
oos.flush();
oos.close();

反序列化:

//反序列化
FileInputStream fis=new FileInputStream("D:\\aaa\\student.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
//反序列化集合
List list=(List)ois.readObject();
//遍历集合并输出
for(Student s:list) {System.out.println(s);
}
ois.close();
/*
输出:Student{name=Alice,age=3}Student{name=bob,age=5}Student{name=rose,age=2}
*/

transient关键字

transient关键字表示游离的,不参与序列化:

//name用transient关键字修饰,表示name不参与序列化操作
private transient String name;

序列化优点

  1. 将对象转为字节流存储到硬盘上,当JVM停机时,字节流还会在硬盘上默默等待,等待下一处JVM的启动,把序列化的对象通过反序列化为原来的对象,并且序列化的二进制序列能够减少存储空间(永久性保存对象)
  2. 序列化成字节流的对象可以进行网络传输(二进制形式),方便网络传输
  3. 通过序列化可以在进程间传递对象

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...