JavaRush /Курсы /Java Core /Сериализация. Начало.

Сериализация. Начало.

Java Core
10 уровень , 3 лекция
Открыта

— Помнишь, мы сегодня разбирали сохранение объектов в файл и чтение из файла?

— Да, только мы сохраняли в поток вывода, а читали из потока ввода.

— Молодец, Амиго. Приятно слышать, что ты замечаешь такие мелочи. А ты бы смог дописать код, чтобы было сохранение в файл и чтение из файла?

— А что там писать?! Объявил FileInputStream и FileOutputStream и передавай их в методы save & load. Тут уже ничего не перепутаешь — все просто.

— Рада за тебя. Итак, новая тема – сериализация.

Сериализация – это практически то же самое, что мы с тобой только что делали, только гораздо круче и встроено прямо в Java-машину. Java-машина умеет сохранять и загружать свои объекты. Для этого ей даже не требуются методы save & load: все объекты хранятся внутри Java-машины, и она имеет к ним полный доступ.

Мы просто берем объект и сохраняем его в поток/читаем из потока:

Код
public static void main(String[] args) throws Exception {
     Cat cat = new Cat();

    //save cat to file
    FileOutputStream fileOutput = new FileOutputStream("cat.dat");
    ObjectOutputStream outputStream = new ObjectOutputStream(fileOutput);
    outputStream.writeObject(cat);
    fileOutput.close();
    outputStream.close();

    //load cat from file
    FileInputStream fiStream = new FileInputStream("cat.dat");
    ObjectInputStream objectStream = new ObjectInputStream(fiStream);
    Object object = objectStream.readObject();
    fiStream.close();
    objectStream.close();

    Cat newCat = (Cat)object;
}

— И все?

— Да. Там очень большой и сложный механизм сериализации, который поддерживает сохранение в поток и чтение из потока почти всех типов данных.

— Почти всех, это значит не всех?

— Да, дело в том, что не все объекты по своей сути можно сохранить. Некоторые объекты не хранят все свои данные в себе, а лишь ссылаются на другие объекты и/или источники данных. Например, консоль (System.in), поток ввода (InputStream), или что-нибудь еще.

Поэтому разработчики Java придумали специальный интерфейс-маркер – Serializable. Его называют маркером, т.к. он не содержит никаких данных и методов. Он используется только для того, чтобы «помечать» (маркировать) классы. Если мы считаем, что наш класс хранит в себе все свои данные, тогда мы можем пометить его этим маркером – написать implements Serializable.

Пример «кота» с поддержкой сериализации:

Код
class Cat implements Serializable {
    public String name;
    public int age;
    public int weight;
}

Когда мы пытаемся сериализовать (сохранить) какой-нибудь объект, Java-машина проверяет – поддерживает ли он сериализацию: реализует ли он интерфейс Serializable? Если да, то сохраняет объект, если нет – выкидывает исключение о невозможности сериализации.
Тут нужно понимать, что сериализуемый объект должен состоять тоже только из сериализуемых объектов.

— Ну, этого и следовало ожидать. Нельзя же сохранить целое, не сохранив какие-то его части.

— Именно так.

— А как же типы int, String, ArrayList?

— Они все поддерживают сериализацию, на этот счет разработчики Java специально позаботились. Тут проблем быть не должно.

Более того, при сериализации объекта сохраняется его тип. Теперь ты можешь в переменную класса с типом Object сохранить ссылку на объект Cat, и все это отлично сериализуется и десериализуется.

— Десериализуется?

Десериализация – так называют процесс, обратный сериализации – чтение и восстановление объекта из потока/файла.

— Тогда вопросов больше нет.

Комментарии (192)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3585174 Уровень 33
16 сентября 2025
Like
Yury Уровень 51
15 мая 2025
FileInputStream fiStream = new FileInputStream("cat.dat"); ObjectInputStream objectStream = new ObjectInputStream(fiStream); Object object = objectStream.readObject(); fiStream.close(); objectStream.close(); Зачем дважды закрывать поток? ObjectInputStream - Это же ведь обёртка!
Vyacheslav Уровень 30 Expert
19 мая 2025
Возможно просто для надежности) Ошибки никакой не будет в любом случае. Может быть из-за того что до Java 7 не было try with resources и привычка везде прописывать close() сохранилась.
Ruslan Skalden Уровень 36
1 августа 2025
Все верно, обертка закрывает вложенный класс, во возможные варианты почему так делают: - Лишняя предосторожность (на всякий случай — особенно у начинающих). - Копипаст из примеров, где потоки создаются отдельно. - Потенциальная поддержка старого кода, где были нестабильные реализации или альтернативные потоки.
ВК Уровень 36
14 декабря 2024
Пытливым умам сразу интересно, что будет если попытаться сериализовать перекрестные ссылки. Например, у объекта "Кот" есть ссылка на мышь, которую он преследует. У объекта "мышь" - ссылка на кота, который её преследует. Не получится ли тут циклических ссылок и зависаний? Мой пытливый ум проверил эту идею в "идее" - и все и сохранилось, и загрузилось корректно. Магия, однако...
Kaz Уровень 32
7 октября 2024
устал чот от задачек, вот бы следующая лекция была лекция, а не куча задач опять)
illirenz Уровень 3
25 июня 2024
Решил не делать ни одной задачи из прошлой лекции, не хочется тратить время на то, что не пригодится никогда. Если вдруг появится огромное количество времени, ради интереса займусь, а пока ну нафиг.
Igoreek Уровень 43
19 августа 2024
ну в тех задачках отрабатывается не только костыльный метод сериализации который никогда не пригодится, в них отрабатываются навыки работы со всякими методами... "знать методы " != " уметь пользоваться методами" есть польза от них
JavaRusher853 Уровень 36
20 августа 2024
Не просто плюсую а умножаю.
26 августа 2024
Моё уважение.
Евгений Уровень 37
18 июля 2025
Я всё-таки решил потратить время на задачки. В каждой задаче подсматривал решение по несколько раз, пытался разобраться почему так а не иначе. В итоге очень доволен, многое понял
4el0vek3 Уровень 36
12 августа 2025
Слабак
invoker main Уровень 42
9 октября 2025
ты что ли
Максим Li Уровень 40
11 мая 2024
11.05.2024
Shhopat Уровень 51
26 марта 2024
кто то может сказать где это нужно. в лекции все ясно но не ясно зачем это нужно и что там под "капотом"
Natalya Уровень 39
8 апреля 2024
В среде Eclipse Serializable используется. Если работать в IDEA этот маркер мало используется, есть другие инструменты. Но знать как под капотом устроено, необходимо.
YarDK_3 Уровень 23
18 апреля 2024
У тебя есть некоторый объект класса Person. Стоит задача - передать этот экземпляр класса вне твоей программы. Очевидно сделать это можно, если ты создашь какой-то файл, в котором будет храниться информация о твоем объекте. Что бы каждый раз не писать велосипеды, существует этот интерфейс, который грубо говоря стандартизирует процесс.
Duxa552 Уровень 1
17 сентября 2024
сохранения в играх по таком принципу работают
Anonymous #3390940 Уровень 38
10 февраля 2024
Сериализация объектов в Java - это процесс, используемый для преобразования объекта в двоичный формат, который может быть сохранен на диск или отправлен по сети на любую другую работающую виртуальную машину Java; обратный процесс создания объекта из двоичного потока называется десериализацией. Топ-13 вопросов про сериализацию на собеседования
Big Sam Уровень 32 Expert
10 января 2024
Интересная лекция
Алексей Уровень 40 Expert
17 декабря 2023
Хорошая лекция)