• 【Java-----IO流(八)之对象专属流详解】


    序列化和反序列化定义

    • 序列化:指把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接口只是一个标志接口:

    1. public interface Serializable{
    2. }

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

    序列化版本号的作用

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

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

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

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

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

    例:

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

    对象序列化代码实现

    对象类:

    1. public class Student implements Serializable {
    2. int age;
    3. String name;
    4. public Student() {
    5. }
    6. public Student(int age,String name) {
    7. this.name=name;
    8. this.age=age;
    9. }
    10. public void setName(String name) {
    11. this.name=name;
    12. }
    13. public String getName() {
    14. return name;
    15. }
    16. public void setAge(int age) {
    17. this.age=age;
    18. }
    19. public int getAge() {
    20. return age;
    21. }
    22. public String toString() {
    23. return "Student{name="+name+","+"age="+age+"}";
    24. }
    25. }

    序列化:

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

    反序列化对象代码实现

    反序列化:

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

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

    序列化:

    1. //创建集合存放对象
    2. List studentList=new ArrayList();
    3. //创建对象
    4. Student s1=new Student(3,"Alice");
    5. Student s2=new Student(5,"bob");
    6. Student s3=new Student(2,"rose");
    7. //将对象存入集合
    8. studentList.add(s1);
    9. studentList.add(s2);
    10. studentList.add(s3);
    11. //序列化
    12. FileOutputStream fos=new FileOutputStream("D:\\aaa\\student.txt");
    13. ObjectOutputStream oos=new ObjectOutputStream(fos);
    14. //序列化一个集合
    15. oos.writeUnshared(studentList);
    16. oos.flush();
    17. oos.close();

    反序列化:

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

    transient关键字

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

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

    序列化优点

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

  • 相关阅读:
    基于单片机的老人防丢系统设计
    2022 计网复习简答题【太原理工大学】
    C++语言之虚函数、多态、抽象类
    vue3.0 ref的使用
    开源框架中的责任链模式实践
    Linux 网络配置
    C#操作modbus
    mysql 安装问题 mariadb-libs is obsoleted by mysql-community-libs
    Java 开发5年了想转项目经理有可能吗?有pmp证书
    1x1卷积的作用
  • 原文地址:https://blog.csdn.net/qq_45071131/article/details/127803496