Сериализация — это механизм преобразования объекта в поток байтов для последующего хранения или передачи. В Java сериализация появилась вместе с платформой в версии 1.1 как часть API ввиду популярности распределённых приложений и необходимости обмена данными между ними. Это решение позволяло упростить передачу сложных графов объектов между JVM и хранение их состояния, сделав процесс прозрачным для разработчика.
Проблема сериализации заключается в том, что необходимо строго соблюдать целостность данных, поддерживать версионирование классов и корректно обрабатывать сложные структуры (например, графы с циклическими ссылками). Не все объекты сериализуемы (например, потоки, сокеты, ресурсы ОС), и сериализация требует особого внимания к безопасности.
Решение реализовано с помощью интерфейса Serializable:
import java.io.*; class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private transient int age; // не сериализуется public Person(String name, int age) { this.name = name; this.age = age; } }
С помощью ObjectOutputStream и ObjectInputStream объект можно записать в файл и восстановить:
Person p = new Person("Alice", 30); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser")); oos.writeObject(p); // сериализация ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser")); Person restored = (Person) ois.readObject();
Ключевые особенности:
Serializable.transient не сериализуются.Можно ли сериализовать объект с несериализуемым полем, даже если оно не используется?
Ответ: Если поле отмечено как transient, оно не сериализуется вообще, и процесс не завершится исключением, даже если его тип не реализует Serializable. Если поле несериализуемо и не transient, будет выброшено исключение NotSerializableException.
Является ли сериализуемым статическое поле, если класс реализует Serializable?
Ответ: Нет, статические поля не сериализуются, потому что они принадлежат классу, а не экземпляру. Только состояние экземпляра сохраняется.
Что произойдёт, если изменить структуру класса после сериализации (например, добавить или удалить поле)?
Ответ: Если указываете версию serialVersionUID, и структура изменилась несовместимо, при десериализации появится InvalidClassException. Для обеспечения совместимости используют сериализаторские хинты и ручное управление serialVersionUID.
Инженеры решили сериализовать объект, не добавив serialVersionUID и не объявив поля, которые ссылаются на ресурсы ОС, как transient. После обновления приложения и класса возник InvalidClassException и объект утратил целостность, а десериализация перестала работать.
Плюсы:
Минусы:
Для сериализации был реализован переносимый класс с явным serialVersionUID, все поля-ресурсы объявлены как transient, а ручная сериализация контролирует ключевые моменты.
Плюсы:
Минусы: