понедельник, 5 декабря 2011 г.

Сериализация статических полей

Сериализация (serialization) объектов Java позволяет взять вам любой объект, реализующий интерфейс Serializable, и превратить его в последовательность байтов, из которой затем можно полностью восстановить исходный объект.
Чтобы сериализовать объект, требуется создать выходной поток OutputStream, который нужно вложить  объект ObjectOutputStream. По сути, вызов метода writeObject() осуществляет сериализацию объекта, и далее вы пересылаете его в выходной поток данных OutputStream. Для восстановления объекта необходимо надстроить объект ObjectInputStream для входного потока InputStream, а затем вызвать метод readObject(). Этот метод возвращает ссылку на объект типа Object, поэтому после вызова метода следует провести нисходящее преобразование для получения объекта нужного типа.
Давайте рассмотрим пример сериализации:
import java.io.*;

class A implements Serializable{
    private static int n=0;
    private int i;
    A(int i){
        this.i=i;
        n=i;
    }
    public String toString(){
        return i+" "+n;
    }
}

public class Temp{
    public static void main(String []args) throws IOException,ClassNotFoundException {
        A a = new A(5);
        System.out.println(a);
        String path = "serial.dat";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
        oos.writeObject(a);
        a = new A(10);
        System.out.println(a);
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        a = (A)ois.readObject();
        System.out.println(a);
    }
}
Вывод этой программы будет следующий:
5 5
10 10
5 10

Итак, мы сериализовали объект со значением поля i=5 и значением статического поля n=5, создали новый объект(i=10,n=10), и десериализовали записанный объект. Как видим, обычное поле успешно десериализовалось, а вот статическое осталось без изменений. Если вам нужно сериализовать статические поля, вы должны делать это вручную. Исправим нашу предыдущую программу так, чтобы она сохраняла статическую переменную:
import java.io.*;

class A implements Serializable{
    private static int n=0;
    private int i;
    A(int i){
        this.i=i;
        n=i;
    }
    public String toString(){
        return i+" "+n;
    }
    public static void serializeStatic(ObjectOutputStream oos) throws IOException{
        oos.writeInt(n);
    }
    public static void deserializeStatic(ObjectInputStream ois) throws IOException{
        n=ois.readInt();
    }
}

public class Temp{
    public static void main(String []args) throws IOException,ClassNotFoundException {
        A a = new A(5);
        System.out.println(a);
        String path = "serial.dat";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
        A.serializeStatic(oos);
        oos.writeObject(a);
        a = new A(10);
        System.out.println(a);
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        A.deserializeStatic(ois);
        a = (A)ois.readObject();
        System.out.println(a);
    }
}
Вывод:
5 5
10 10
5 5

Как видите, теперь все в порядке. Мы просто добавили и вызвали два статических метода: для сериализации и десериализации статической переменной.
Всего хорошего!

Комментариев нет:

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.