Философия Java


Альтернатива Externalizable - часть 2


Может показаться, что когда вы вызываете ObjectOutputStream.writeObject( ), объект с интерфейсом Serializable, который вы передаете, опрашивается (используя рефлексию, не имеет значения) на предмет реализации своего собственного writeObject( ). Если это так, то нормальный процесс сериализации пропускается, и вызывается writeObject( ). Аналогичная ситуация наблюдается и для readObject( ).

Есть еще один поворот. Внутри вашего writeObject( ) вы можете выбрать выполнение стандартного действия writeObject( ), вызвав defaultWriteObject( ). Точно так же, внутри readObject( ) вы можете вызвать defaultReadObject( ). Вот пример, который демонстрирует, как вы можете управлять хранением и восстановлением объектов с интерфейсом Serializable:

//: c11:SerialCtl.java

// Управление сериализацией, путем добавления

// собственных методов writeObject() и readObject().

import java.io.*;

public class SerialCtl implements Serializable { String a; transient String b; public SerialCtl(String aa, String bb) { a = "Not Transient: " + aa; b = "Transient: " + bb; } public String toString() { return a + "\n" + b; } private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); stream.writeObject(b); } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); b = (String)stream.readObject(); } public static void main(String[] args) throws IOException, ClassNotFoundException { SerialCtl sc = new SerialCtl("Test1", "Test2"); System.out.println("Before:\n" + sc); ByteArrayOutputStream buf = new ByteArrayOutputStream(); ObjectOutputStream o = new ObjectOutputStream(buf); o.writeObject(sc); // Теперь получим это назад:

ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( buf.toByteArray())); SerialCtl sc2 = (SerialCtl)in.readObject(); System.out.println("After:\n" + sc2); } } ///:~

В этом примере есть одно обычное поле String, а другое имеет модификатор transient, для обеспечения возможности сохранения не transient поля с помощью метода defaultWriteObject( ), а transient поля сохраняются и восстанавливаются явно. Поля инициализируются внутри конструктора, а не в точке определения, чтобы удостоверится, что они не инициализируются каким-либо автоматическим механизмом во время десериализации.




Начало  Назад  Вперед