Что такое сериализация объектов?

«Что такое сериализация объектов?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Сериализация — это процесс преобразования состояния объекта (его полей и данных) в последовательность байтов. Эта последовательность может быть сохранена в файл, передана по сети или сохранена в базу данных. Обратный процесс восстановления объекта из байтов называется десериализацией.

Основные цели:

  • Сохранение состояния: Для последующего восстановления (например, чекпоинты в играх, настройки).
  • Передача объектов: В распределенных системах (RPC, сообщения между микросервисами).
  • Кэширование: Сохранение сложных структур данных.

Пример сериализации в Java (с использованием java.io.Serializable):

import java.io.*;

// Класс должен реализовать маркерный интерфейс Serializable
class UserSettings implements Serializable {
    // serialVersionUID для контроля версий класса
    private static final long serialVersionUID = 1L;

    private String theme;
    private int fontSize;
    private transient String temporaryToken; // Поле не будет сериализовано

    // Конструкторы, геттеры, сеттеры...
}

public class SerializationDemo {
    public static void main(String[] args) {
        UserSettings settings = new UserSettings("Dark", 14);

        // СЕРИАЛИЗАЦИЯ (объект -> байты -> файл)
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream("settings.dat"))) {
            oos.writeObject(settings);
            System.out.println("Объект сериализован.");
        } catch (IOException e) { e.printStackTrace(); }

        // ДЕСЕРИАЛИЗАЦИЯ (файл -> байты -> объект)
        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream("settings.dat"))) {
            UserSettings loadedSettings = (UserSettings) ois.readObject();
            System.out.println("Объект десериализован. Тема: " + loadedSettings.getTheme());
        } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }
    }
}

Важные аспекты:

  • transient-поля: Не участвуют в сериализации (например, пароли, кэши).
  • serialVersionUID: Уникальный идентификатор версии класса. Его отсутствие может привести к InvalidClassException при изменении класса.
  • Безопасность: Нативная сериализация Java может быть уязвима. Для межъязыкового обмена часто используют JSON (Jackson, Gson), XML или бинарные форматы (Protocol Buffers, Avro).