Java中的序列化和反序列化

序列化:Serialize,java对象存储到文件中,将java对象的状态保存下来的工程。 反序列化:DeSerialize,将硬盘上的数据重新恢复到内存当中,恢复成java对象。

参与序列化和反序列化的对象,必须实现Serializable接口,这个接口是一个标志接口,起到标识作用,java虚拟机看到某个类实现这个接口,会自动生成一个序列化版本号。

import java.io.*;
import java.util.ArrayList;
import java.util.List;
// 序列化
public class ObjectOutputStreamTest {
    public static void main(String[] args) throws Exception {
        /*// 创建java对象
        Student student1 = new Student("鳄鱼君",18);
        // 序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student"));
        oos.writeObject(student1);
        // 刷新
        oos.flush();
        // 关闭
        oos.close();*/
        // 序列化多个对象
        List<Student> userList = new ArrayList<>();
        userList.add(new Student("鳄鱼君",18));
        userList.add(new Student("爱上我",28));
        userList.add(new Student("富婆",58));
        ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("students"));
        oos.writeObject(userList);
        oos.flush();
        oos.close();
    }
}
class Student implements Serializable {
    private String name;
    // age字段不参与序列化
    // transient表示游离的
    private transient int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
// 反序列化
public class ObjectInputStreamTest {
    public static void main(String[] args) throws Exception{
        /*ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student"));
        // 反序列化
        Object obj = ois.readObject();
        // 反序列化原来是一个学生对象,所以会调用学生对象的toString方法
        System.out.println(obj);*/

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("students"));
        Object obj = ois.readObject();
        System.out.println(obj);
        ois.close();
    }
}

自动生成序列化版本号的优点:区分两个名字相同但实际上不是同一个类(这两个类必须实现Serializable接口),这两个类都会自动生成序列化版本号,Java虚拟机可以根据序列号区分开

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

结论:凡是一个类实现了Serializable接口,应该给该类提供一个固定不变的序列化版本号

class Student implements Serializable {
    // 手动定义序列化版本号
    // java虚拟机识别一个类的时候,先通过类名
    // 类名一致,再通过序列化版本号
    private static final long serialVersionUID = 1L;

    ...
}
Idea工具也可以自动生成序列化

发表评论