Студопедия  
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Управление сериализацией

Читайте также:
  1. Анализ и управление рисками девелопмента.
  2. Б) Управление огнем при отражении атаки
  3. Б) Управление огнем танка в обороне.
  4. В программе 1С: Управление производственным предприятием
  5. Власть и управление страной в переходный период
  6. ВОПРОС 32. ВНЕШНЕЕ УПРАВЛЕНИЕ КАК ПРОЦЕДУРА БАНКРОТСТВА
  7. ВЫХОД ИЗ ТОРГОВЛИ И УПРАВЛЕНИЕ РИСКОМ (УПРАВЛЕНИЕ ДЕНЬГАМИ)
  8. Г) Управление огнем в наступлении ночью.
  9. Генерализованное управление с помощью Стимулов.
  10. Глава 2. Управление физической подготовкой

Как вы можете видеть, стандартный механизм сериализации тривиален в использовании. Но что, если вам нужны специальные требования? Может быть, вы имеете особые требования по безопасности и вы не хотите сериализовать часть вашего объекта, или, может быть, не имеет смысла сериализовать один из подобъектов, если эта часть будет вновь создана при восстановлении объекта.

Вы можете управлять процессом сериализации, реализовав интерфейс Externalizable вместо интерфейса Serializable. Интерфейс Externalizable расширяет интерфейс Serializable и добавляет два метода: writeExternal() и readExternal(), которые автоматически вызываются для вашего объекта во время сериализации и десериализации, так что вы можете выполнить специальные операции.

Следующий пример показывает простую реализацию методов интерфейса Externalizable. Обратите внимание, что Blip1 и Blip2 почти идентичны, за исключением тонких различий (проверьте, сможете ли вы найти их в коде):

//: c11:Blips.java// Простое использование Externalizable & ловушка.import java.io.*;import java.util.*; class Blip1 implements Externalizable { public Blip1() { System.out.println("Blip1 Constructor"); } public void writeExternal(ObjectOutput out) throws IOException { System.out.println("Blip1.writeExternal"); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("Blip1.readExternal"); }} class Blip2 implements Externalizable { Blip2() { System.out.println("Blip2 Constructor"); } public void writeExternal(ObjectOutput out) throws IOException { System.out.println("Blip2.writeExternal"); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("Blip2.readExternal"); }} public class Blips { // Исключения выбрасываются на консоль: public static void main(String[] args) throws IOException, ClassNotFoundException { System.out.println("Constructing objects:"); Blip1 b1 = new Blip1(); Blip2 b2 = new Blip2(); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("Blips.out")); System.out.println("Saving objects:"); o.writeObject(b1); o.writeObject(b2); o.close(); // Теперь получаем их обратно: ObjectInputStream in = new ObjectInputStream(new FileInputStream("Blips.out")); System.out.println("Recovering b1:"); b1 = (Blip1)in.readObject(); // OOPS! Выброшено исключение://! System.out.println("Recovering b2:");//! b2 = (Blip2)in.readObject(); }} ///:~

Вывод для этой программы:

Constructing objects:Blip1 ConstructorBlip2 ConstructorSaving objects:Blip1.writeExternalBlip2.writeExternalRecovering b1:Blip1 ConstructorBlip1.readExternal

Причина того, что объект Blip2 не восстановлен в том, что происходит попытка сделать нечто, что является причиной исключения. Вы нашли различия между Blip1 и Blip2? Конструктор для Blip1 является public, в то время как конструктор для Blip2 не такой, и поэтому появляется исключение во время восстановления. Попробуйте сделать конструктор Blip2 public и удалите комментарии //!, чтобы увидеть корректный результат.

Когда восстанавливается b1, вызывается конструктор по умолчанию для Blip1. Это отличается от восстановления объекта с Serializable, в котором конструирование целиком происходит из сохраненных бит без вызова конструктора. Для объектов Externalizable проявляется обычное поведение конструктора по умолчанию (включая инициализацию в точке определения полей), а затем вызывается readExternal(). Вы должны осознавать это - в частности, тот факт, что все конструкторы по умолчанию занимают свое место - для производства корректного поведения вашего объекта с Externalizable.

Вот пример, который показывает, что вы должны сделать для полного хранение и восстановления объекта с Externalizable:

//: c11:Blip3.java// Реконструирование externalizable объекта.import java.io.*;import java.util.*; class Blip3 implements Externalizable { int i; String s; // Без инициализации public Blip3() { System.out.println("Blip3 Constructor"); // s, i не инициализируется } public Blip3(String x, int a) { System.out.println("Blip3(String x, int a)"); s = x; i = a; // s & i инициализируются только в // конструкторе не по умолчанию. } public String toString() { return s + i; } public void writeExternal(ObjectOutput out) throws IOException { System.out.println("Blip3.writeExternal"); // Вы обязаны сделать это: out.writeObject(s); out.writeInt(i); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("Blip3.readExternal"); // Вы обязаны сделать это: s = (String)in.readObject(); i =in.readInt(); } public static void main(String[] args) throws IOException, ClassNotFoundException { System.out.println("Constructing objects:"); Blip3 b3 = new Blip3("A String ", 47); System.out.println(b3); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("Blip3.out")); System.out.println("Saving object:"); o.writeObject(b3); o.close(); // Теперь получим обратно: ObjectInputStream in = new ObjectInputStream(new FileInputStream("Blip3.out")); System.out.println("Recovering b3:"); b3 = (Blip3)in.readObject(); System.out.println(b3); }} ///:~

Поля s и i инициализируются только во втором конструкторе, но не в конструкторе по умолчанию. Это значит, что если вы не инициализируете s и i в readExternal(), они будут равны null (так как хранилище объектов заполняется нулями при первом шаге создания объектов). Если вы закомментируете две строки кода, следующих за фразой "Вы обязаны сделать это", и запустите программу, вы увидите, что при восстановлении объекта s равно null, а i равно нулю.

Если вы наследуете от объекта с интерфейсом Externalizable, обычно вы будете вызывать методы writeExternal() и readExternal() базового класса для обеспечения правильного хранения и восстановления компонент базового класса.

Таким образом, чтобы сделать все правильно, вы должны не только записать важные данные из объекта в методе writeExternal() (здесь нет стандартного поведения, при котором записывается любой член объекта с интерфейсом Externalizable), но вы также должны восстановить эти данные в методе readExternal(). Сначала это может немного смущать, потому что поведение конструктора по умолчанию объекта с интерфейсом Externalizable может представить все, как некоторый вид автоматического сохранения и восстановления. Но это не так.




Дата добавления: 2015-09-11; просмотров: 20 | Поможем написать вашу работу | Нарушение авторских прав

Конструкторы | Упражнения | Список директории | Поиск и создание директориев | Ввод и вывод | Чтение из InputStream с помощью FilterInputStream | Запись в OutputStream с помощью FilterOutputStream | Неизмененные классы | Типичное использование потоков ввода/вывода | Многофайловое хранение с использованием Zip |


lektsii.net - Лекции.Нет - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав