04-java序列化

一、序列化含义

  序列化:    将对象写入IO流中

  反序列化:从IO流中恢复对象

  目的:       序列化机制允许将实现序列化的Java对象转换为字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。

  使用:  所有在网络上传输的对象/保存到磁盘中的对象必须是可序列化的

  

二、序列化的实现方式

  概述:可通过实现Serializable接口或者Externalizable接口之一处理

  2.1 Serializable

      2.1.1 Serializable接口是一个标记接口,不用实现任何方法。一旦实现了此接口,该类的对象就是可序列化的。

          反序列化并不会调用构造方法。反序列的对象是由JVM自己生成的对象,不通过构造方法生成。

      2.1.2 成员是引用的序列化

          如果一个可序列化的类的成员不是基本类型,也不是String类型,那这个引用类型也必须是可序列化的;否则,会导致此类不能序列化。

      2.1.3 同一对象不会序列化多次

public class WriteTeacher {
    public static void main(String[] args) throws Exception {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("teacher.txt"))) {
            Person person = new Person("路飞", 20);
            Teacher t1 = new Teacher("雷利", person);
            Teacher t2 = new Teacher("红发香克斯", person);
            //依次将4个对象写入输入流
            oos.writeObject(t1);
            oos.writeObject(t2);
            oos.writeObject(person);
            oos.writeObject(t2);
        }
    }
}

依次将t1、t2、person、t2对象序列化到文件teacher.txt文件中。
注意:反序列化的顺序与序列化时的顺序一致。

public class ReadTeacher {
    public static void main(String[] args) {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("teacher.txt"))) {
            Teacher t1 = (Teacher) ois.readObject();
            Teacher t2 = (Teacher) ois.readObject();
            Person p = (Person) ois.readObject();
            Teacher t3 = (Teacher) ois.readObject();
            System.out.println(t1 == t2);
            System.out.println(t1.getPerson() == p);
            System.out.println(t2.getPerson() == p);
            System.out.println(t2 == t3);
            System.out.println(t1.getPerson() == t2.getPerson());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//输出结果
//false
//true
//true
//true
//true

从输出结果可以看出,Java序列化同一对象,并不会将此对象序列化多次得到多个对象。

      2.1.4  Java序列化算法   

      1. 所有保存到磁盘的对象都有一个序列化编码号

      2. 当程序试图序列化一个对象时,会先检查此对象是否已经序列化过,只有此对象从未(在此虚拟机)被序列化过,才会将此对象序列化为字节序列输出。

      3. 如果此对象已经序列化过,则直接输出编号即可

          

 

     2.1.5 java序列化算法潜在的问题

      由于java序利化算法不会重复序列化同一个对象,只会记录已序列化对象的编号。如果序列化一个可变对象(对象内的内容可更改)后,更改了对象内容,再次序列化,并不会再次将此对象转换为字节序列,而只是保存序列化编号。

    2.1.6 可选的自定义序列化

      使用transient关键字选择不需要序列化的字段。

      使用transient修饰的属性,java序列化时,会忽略掉此字段,所以反序列化出的对象,被transient修饰的属性是默认值。对于引用类型,值是null;基本类型,值是0;boolean类型,值是false。

posted @ 2021-10-20 23:11  微~粒  阅读(32)  评论(0)    收藏  举报