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

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

Ответ

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

Основной механизм: Для сериализации объект должен реализовывать интерфейс-маркер java.io.Serializable. Интерфейс java.io.Externalizable предоставляет более детальный контроль над процессом.

Ключевые моменты:

  • transient поля: Поля, помеченные модификатором transient, не участвуют в сериализации.
  • serialVersionUID: Уникальный идентификатор версии сериализованного класса. Используется для проверки совместимости при десериализации. Рекомендуется объявлять его явно как private static final long.
  • Наследование: Если родительский класс реализует Serializable, то и все его дочерние классы сериализуемы. Если родительский класс не сериализуем, то он должен иметь конструктор по умолчанию (без аргументов), который будет вызван при десериализации дочернего объекта.

Пример:

import java.io.*;

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

    private String name;
    private transient int age; // Это поле не будет сериализовано
    private String email;

    public Person(String name, int age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + ", email='" + email + "'}";
    }
}

public class SerializationDemo {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30, "alice@example.com");
        String filename = "person.ser";

        // Сериализация
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
            oos.writeObject(person);
            System.out.println("Объект сериализован: " + person);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Десериализация
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) {
            Person restoredPerson = (Person) ois.readObject();
            // Поле age было transient, поэтому его значение не восстановилось (будет 0)
            System.out.println("Объект десериализован: " + restoredPerson);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}