Вам может быть интересно, что необходимо для восстановления объекта после проведения сериализации. Например, предположим, что вы создали объект, се-риализовали его и отправили в виде файла или через сетевое соединение на другой компьютер. Сумеет ли программа на другом компьютере реконструировать объект, опираясь только на те данные, которые были записаны в файл в процессе сериализации?
Самый надежный способ получить ответ на этот вопрос — провести эксперимент. Следующий файл располагается в подкаталоге данной главы:
//: io/Alien java
// Сериализуемый класс
import java.io.*;
public class Alien implements Serializable {} ///:-
Файл с программой, создающей и сериализующей объект Alien, находится в том же подкаталоге:
// io/FreezeAlien java
// Создание файла с данными сериализации
import java io *,
public class FreezeAlien {
public static void main(Stnng[] args) throws Exception { ObjectOutput out = new ObjectOutputStream( new FileOutputStreamC'X file")). Alien quellek = new AlienO. out writeObject(quellek),
}
Вместо того чтобы перехватывать и обрабатывать исключения, программа идет по простому пути — исключения передаются за пределы main(), поэтому сообщения о них будут выдаваться на консоль.
После того как вы скомпилируете и запустите этот код, в каталоге с12 появится файл с именем X.file. Следующая программа скрыта от чужих глаз в «секретном» подкаталоге xfiles:
//• io/xfi1es/ThawAlien java
// Попытка восстановления сериализованного файла
// без сохранения класса объекта в зтом файле.
// {RunByHand}
import java io *,
public class ThawAlien {
public static void main(Strmg[] args) throws Exception { ObjectInputStream in = new ObjectInputStream(
new FileInputStream(new FileC. ". "X file"))). Object mystery = in readObjectO, System out println(mystery getClassO),
}
} /* Output
class Alien */// -
Даже открыв файл и прочитав из него данные для восстановления объекта mystery, виртуальная машина Java QVM) не сможет найти файл Alien.class; объект Class для объекта Alien будет в не досягаемости (в примере сознательно не рассматривается возможность обнаружения через переменную окружения CLASSPATH). Возникнет исключение ClassNotFoundException.
Управление сериализацией
Как вы могли убедиться, стандартный механизм сериализации достаточно прост в применении. Но что, если у вас возникли особые требования? Возможно, из соображений безопасности вы не хотите сохранять некоторые части вашего объекта, или сериализовать какой-либо объект, содержащийся в главном объекте, не имеет смысла, так как немного погодя его все равно потребуется создать заново.
Вы можете управлять процессом сериализации, реализуя в своем классе интерфейс Externalizable вместо интерфейса Serializable. Этот интерфейс расширяет оригинальный интерфейс Serializable и добавляет в него два метода, writeExternal() и readExternal(), которые автоматически вызываются в процессе сериализации и восстановления объектов, позволяя вам попутно выполнить специфические действия для конкретного объекта.
В следующем примере продемонстрирована простая реализация интерфейса Externalizable. Заметьте также, что классы Blipl и Blip2 практически одинаковы, если не считать одного малозаметного отличия:
// io/Blips.java
// Простая реализация интерфейса Externalizable. . с проблемами
import java io *;
import static net mindview util Print *;
class Blipl implements Externalizable {
public BliplO {
print("Конструктор Blipl"),
}
public void writeExternal(ObjectOutput out) throws IOException { print("Blipl writeExternal"),
}
public void readExternal(Objectlnput in)
throws IOException, ClassNotFoundException { print("Blipl readExternal");
class Blip2 implements Externalizable { Blip2() {
print("Конструктор Blip2");
}
public void writeExternal(ObjectOutput out) throws IOException { print("Blip2.writeExternal"),
}
public void readExternal(Objectlnput in)
throws IOException, ClassNotFoundException { print("Blip2.readExternal"),
public class Blips {
public static void main(String[] args) throws IOException, ClassNotFoundException { print("Создание объектов:"); Blipl bl = new BliplO; Blip2 b2 = new Blip20,
ObjectOutputStream о = new ObjectOutputStream(
new FileOutputStream("Blips out")); print("Сохранение объектов-"); o.writeObject(bl); о write0bject(b2); о closeO;
// Восстановление сохраненных объектов-
ObjectInputStream in = new ObjectInputStream(
new FileInputStream("Blips out")); print("Восстановление bl:"); bl = (Bli pi)i n.readObject(); // Вот те раз! Исключение //! print("Восстановление Ь2:");
//! Ь2 = (Blip2)in readObjectО; }
} /* Output: Создание объектов-Конструктор Blipl Конструктор Blip2 Сохранение объектов: Blipl writeExternal Blip2 writeExternal Восстановление bl: Конструктор Blipl Blipl readExternal *///:-