序列化代理模式

我們知道,實現了序列化的類。在反序列化時,實例的創建是由readObject方法來完成的。由於這是一個不同於構造函數的創建類實例的通道,因此在構造函數中的狀態約束條件在readObjetc中也得一條不落下的實現。這很讓人頭大,因此這裏介紹一種模式,將實例的反序列化也交給改造函數來完成,即序列化代理模式。要想穩健的將帶有重要約束條件的對象序列化時,這種模式可能是最容易的方法。代碼如下:


import java.io.*;
import java.util.EnumSet;

/**
 * Created by xuyizhen on 2017/5/18.
 */
public class Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Person person = new Person("E-臻", 12);
        File file = new File("C:\\test.txt");

        FileOutputStream fileOutputStream = new FileOutputStream(file);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(person);

        objectOutputStream.flush();
        objectOutputStream.close();
        fileOutputStream.close();

        FileInputStream fileInputStream = new FileInputStream(file);
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        Person person1 = (Person) objectInputStream.readObject();

        objectInputStream.close();
        fileInputStream.close();

        System.out.println(person1);

    }
}

final class Person implements Serializable {

    private String name;
    private int age;

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

    public int getAge() {
        return age;
    }

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

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

    private static class SerializationProxy implements Serializable {
        private String name;
        private int age;

        public SerializationProxy(Person p) {
            this.name = p.name;
            this.age = p.age;
        }

        private Object readResolve() {
            System.out.println("反序列化時使用的類");
            return new Person(name, age);
            //序列化代理模式的精髓,反序列化不再是通過不可控的readObject()途徑,而是通過正常的構造函數途徑。
        }
    }

    private Object writeReplace() {
        System.out.println("序列化時使用的類");
        return new SerializationProxy(this);
    }

    private void readObject(java.io.ObjectInputStream in)
            throws IOException, ClassNotFoundException {
        throw new InvalidObjectException("proxy required");
    }
}

筆者開設了一個知乎live,詳細的介紹的JAVA從入門到精通該如何學,學什麼?

提供給想深入學習和提高JAVA能力的同學,歡迎收聽https://www.zhihu.com/lives/932192204248682496



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章