Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
56_Java.pdf
Скачиваний:
210
Добавлен:
18.02.2016
Размер:
2.39 Mб
Скачать

Скачано с сайта http://ivc.clan.su

ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(x);

Метод readObject() интерфейса java.io.Objectlnput возвращает десериализованный объект. Сначала данный метод считывает из потока имя класса, точнее — объект java.io.ObjectStreamClass (при передаче данных об объекте в поток oos сохраняется и соответствующий объект ObjectStreamClass, который содержит информацию о классе, в том числе полное имя класса). Затем метод находит объект java.lang.Class этого класса в обычном пути класса. Как только объект Class найден, JVM размещает экземпляр класса и восстанавливает значения полей, не являющихся transient и static, как в классе, так и в каждом из его сериализуемых суперклассов. Поля, значения которых не встречаются в потоке, устанавливаются в значения по умолчанию. В процессе обработки тип объекта утрачивается, и обычно необходимо выполнить приведение объекта к соответствующему типу.

Например:

FilelnputStream fin = new FileInputStream("data.ser"); ObjectlnputStream ois = new ObjectlnputStreamf(fin); String dataString = (String)ois.readObject();

Data data = (Data)ois.readObject();

Пример с сериализацией (см. SerializationDemo.java)

В программе используется сериализация и десериализация объектов. В методе main() основного класса создается объект object1 класса MyClass. Этот объект имеет три экземплярные переменные типа String, int, double. Данную информацию необходимо сохранить и восстановить.

Создаётся FileOutputStream-объект (fos), который ссылается на файл с именем "serial", и ObjectOutputStream-объект (oos) для этого файлового потока. Затем для сериализации объекта object1 вызывается метод writeObject() класса ObjectOutputStream. Объектный выходной поток сбрасывается и закрывается.

Затем создаётся FileInputStream-объект (fis), который ссылается на файл "serial", и ObjectInputStream-объект (ois) для этого файлового потока. Затем для десериализации ранее сериализованного объекта в object2 используется метод readObject() класса ObjectlnputStream и объектный входной поток закрывается.

Обратите внимание! Класс MyClass реализует интерфейс Serializable. Если не объявить реализацию этого интерфейса, то будет выброшено исключение типа NotSerializableException.

Попробуйте поэкспериментировать с программой, используя в качестве объекта для сериализации экземпляр какого-нибудь другого класса, указывая при объявлении поля сериализуемого класса модификатор transient и т.д.

Настройка сериализации

Иногда необходимо настраивать механизм сериализации. Например, имеется необходимость всегда сохранять одно и то же значение некоторого поля, независимо от его текущего значения. Возможно, нужно устанавливать значения некоторых transient-полей, не сохраненных во время сериализация объекта.

Существует два способа настройки:

1.Поддержка методов readObject() и writeObject().

2.Реализация интерфейса java.io.Externalizable.

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

50

Скачано с сайта http://ivc.clan.su

Методы readObject и writeObject

Когда объект некоторого класса сериализуют, передавая ссылку на объект методу writeObject() класса ObjectOutputStream, то, как правило, для перезаписи значения полей объекта, не являющихся static и transient, используется метод defaultWriteObject() в ObjectOutputStream. Можно настроить

способ перезаписи данных путем добавления в класс метода writeObject() с объявлением: private void writeObject(ObjectOutputStream out) throws IOException

Если сериализуемый класс имеет свой собственный метод writeObject(), то этот метод вызывается вместо метода defaultWriteObject() в ObjectOutputStream.

Аналогично, если сериализуемый класс имеет метод readObject() с объявлением: private void readObjec(ObjectlnputStream in)

throws IOException, ClassNotFoundException

и объект класса десериализуется с помощью метода readObject() класса ObjectOutputStream, то именно метод readObject() сериализуемого класса будет использоваться вместо метода defaultReadObiect() в

ObjectlnputStream.

Эти методы не объявляются ни в каком интерфейсе или суперклассе. ObjectlnputStream и ObjectOutputStream проверяют, существуют ли такие методы в классе сериализуемого объекте. Если да,

то они вызываются вместо defaultWriteObject() и defaultReadObject().

Интерфейс Externalizable

Интерфейс является интерфейсом, производным от java.io.Serializable: public interface Externalizable extends Serializable

и используется вместо Serializable.

Интерфейс java.io.Externalizable объявляет методы readExternal() и writeExternal(): public abstract void writeExternal (ObjectOutput out)

throws IOException;

public abstract void readExternal (Objectlnput in) throws IOException, ClassNotFoundException.

Входной и выходной объектный поток используют их вместо readObject() или writeObject() соответственно.

Метод writeExternal() записывает состояние объекта в ObjectOutput, передавая объект в качестве параметра. Метод readExternal() считывает состояние объекта из Objectlnput, передавая объект в качестве параметра, и восстанавливает это состояние объекта.

Объекты типа Externalizable ответственны за сохранение и восстановление не только своего собственного состояния, но и любого актуального состояния в их суперклассе. Сериализуемые объекты обрабатывают состояние суперкласса автоматически; externalizable-объекты такой возможности не имеют.

Создание экземпляров сериализованных Bean

Технология JavaBeans позволяет настроить компонент, т.е. указать его свойства в среде визуального проектирования, а затем сохранить их значения в файле с расширением .ser для последующего использования в составе некоторой программы. При этом в программе для создания экземпляра сериализованного Bean следует использовать не оператор new. Используется статический метод instantiate(), который определён в классе java.beans.Beans:

public static Object instantiate(ClassLoader cl, String beanName) throws IOExceptipn, ClassNotFoundException

Этот метод создает экземпляр Bean. Квалифицированное имя класса (либо имя файла сериализованного компонента) задаётся параметром beanName. Загрузчик класса указывается в параметре cl. Если ссылка cl равна null, то по умолчанию применяется системный загрузчик класса.

51

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]