English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Java предоставляет механизм объектной сериализации, в котором объект может быть представлен в виде последовательности байтов, включающей данные объекта, информацию о типе объекта и типы данных, хранящихся в объекте.
После записи сериализованного объекта в файл его можно считывать из файла и десериализовать, то есть информация о типе объекта, данные объекта и типы данных, хранящихся в объекте, могут быть использованы для создания нового объекта в памяти.
В整个过程 независим от виртуальной машины Java (JVM), что означает, что объект, сериализованный на одной платформе, может быть десериализован на другой платформе, совершенно отличной от первой.
Классы ObjectInputStream и ObjectOutputStream являются высокоуровневыми потоками данных, они содержат методы десериализации и сериализации объектов.
Класс ObjectOutputStream содержит множество методов для записи различных типов данных, но есть одно исключение:
public final void writeObject(Object x) throws IOException
Этот метод сериализует объект и отправляет его в поток. Подобный класс ObjectInputStream содержит следующий метод десериализации объекта:
public final Object readObject() throws IOException ClassNotFoundException
Этот метод извлекает следующий объект из потока и десериализует объект. Возвращает Object, поэтому вам нужно преобразовать его в подходящий тип данных.
Для демонстрации работы сериализации в Java я буду использовать класс Employee, о котором говорилось в предыдущем курсе, предполагается, что мы определили следующий класс Employee, который реализует интерфейс Serializable.
public class Employee implements java.io.Serializable { public String name; public String address; public transient int SSN; public int number; public void mailCheck() { System.out.println("Otklik po adrese " + name + " " + address); } }
Обратите внимание, что для успешной сериализации объекта класса необходимо выполнить две условия:
Класс должен реализовывать интерфейс java.io.Serializable.
Все свойства класса должны быть сериализуемыми. Если у свойства нет возможности быть сериализуемым, то это свойство должно быть помечено как временный.
Если вы想知道, является ли стандартный класс Java сериализуемым, обратитесь к документации класса. Проверка того, можно ли сериализовать пример класса, очень проста: нужно проверить, реализует ли этот класс интерфейс java.io.Serializable.
Класс ObjectOutputStream используется для сериализации объекта. Пример SerializeDemo демонстрирует создание объекта Employee и его сериализацию в файл.
После выполнения этой программы создается файл с именем employee.ser. Программа не имеет никакого вывода, но вы можете понять ее действие, изучив код.
Внимание: При序列изации объекта в файл, по стандартным соглашениям Java файлу присваивается расширение .ser.
import java.io.*; public class SerializeDemo { public static void main(String [] args) { Employee e = new Employee(); e.name = "Reyan Ali"; e.address = "Phokka Kuan, Ambehta Peer"; e.SSN = 11122333; e.number = 101; try { FileOutputStream fileOut = new FileOutputStream("/tmp/employee.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(e); out.close(); fileOut.close(); System.out.printf("Сerialized data is saved in /tmp/employee.ser"); catch(IOException i) { i.printStackTrace(); } } }
Ниже приведен пример программы DeserializeDemo, которая демонстрирует десериализацию, объект Employee хранится в файле /tmp/employee.ser.
import java.io.*; public class DeserializeDemo { public static void main(String [] args) { Employee e = null; try { FileInputStream fileIn = new FileInputStream("/tmp/employee.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); e = (Employee) in.readObject(); in.close(); fileIn.close(); catch(IOException i) { i.printStackTrace(); return; catch(ClassNotFoundException c) { System.out.println("Класс сотрудника не найден"); c.printStackTrace(); return; } System.out.println("Десериализация сотрудника..."); System.out.println("Имя: " + e.name); System.out.println("Адрес: " + e.address); System.out.println("SSN: " + e.SSN); System.out.println("Номер: " + e.number); } }
Результат компиляции и выполнения программы приведен ниже:
Десериализованный Employee... Имя: Reyan Ali Адрес: Phokka Kuan, Ambehta Peer SSN: 0 Number:101
Следующие моменты следует учитывать:
Блок try/catch в методе readObject() пытается перехватить исключение ClassNotFoundException. Для того чтобы JVM могла десериализовать объект, класс, который может быть десериализован JVM, должен быть доступен для поиска байт-кода. Если JVM не может найти этот класс во время процесса десериализации объекта, она выбрасывает исключение ClassNotFoundException.
Обратите внимание, что возвращаемое значение метода readObject() преобразуется в ссылку на Employee.
Когда объект сериализуется, значение свойства SSN составляет 111222333, но поскольку это свойство является кратковременным, это значение не было отправлено в поток вывода. Поэтому после десериализации свойство SSN объекта Employee равно 0.