English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Основной курс Java

Java Управление потоком

Java Массивы

Java Ориентированность на объекты (I)

Java Ориентированность на объекты (II)

Java Ориентированность на объекты (III)

Обработка исключений Java

Java Списки (List)

Java Queue (очередь)

Java Map-сборники

Java Set-сборники

Java Ввод/вывод (I/O)

Java Reader/Writer

Другие темы Java

Java сериализация

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.