概念

Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。

将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。

整个过程都是 Java 虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。

实现

方法

类 ObjectInputStream 和 ObjectOutputStream 是高层次的数据流,它们包含反序列化和序列化对象的方法。

public final void writeObject(Object x) throws IOException

writeObject方法序列化一个对象,并将它发送到输出流。

相似的 ObjectInputStream 类包含如下反序列化一个对象的方法:

public final Object readObject() throws IOException, ClassNotFoundException

readObject方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,你需要将它转换成合适的数据类型。

请注意,一个类的对象要想序列化成功,必须满足两个条件:

  • 该类必须实现 java.io.Serializable 接口。
  • 该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的。

如果你想知道一个 Java 标准类是否是可序列化的,请查看该类的文档。检验一个类的实例是否能序列化十分简单, 只需要查看该类有没有实现*java.io.Serializable*接口。

当序列化一个对象到文件时, 按照 Java 的标准约定是给文件一个 .ser 扩展名。 对于一个实体类,不想将所有的属性都进行序列化,有专门的关键字 transient

private transient String name;

当对该类序列化时,会自动忽略被 transient 修饰的属性。

代码

/**
 * 序列化测试
 *
 */
public class App {
    /**
     * Person
     */
    public static class Person implements Serializable {

        private String name;
        private int age;
        private transient String info = "nothing";

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

        public Person setInfo(String info) {
            this.info = info;
            return this;
        }
        public void show(){
            System.out.println(name + '-' + age + '-' + info);
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        writePerson();
        readPerson();
    }

    // 从文件中读取Person对象
    public static void readPerson() throws IOException, ClassNotFoundException {
        // 创建反序列化流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("\\dls.ser"));
        // 从文件中读取对象
        Object obj = ois.readObject();
        ((Person) obj).show();
        // 释放资源
        ois.close();
    }

    // 向文件中写Person对象
    public static void writePerson() throws IOException {
        // 创建序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("\\dls.ser"));
        // 向文件中写Person对象
        oos.writeObject(new Person("大老师", 17).setInfo("没有期望就没有失望,没有羁绊就不会受伤。"));
        // 关流
        oos.close();
    }
}

输出

大老师-17-null

参考资料

[Java 序列化 菜鸟教程](https://www.runoob.com/java/java-serialization.html)