Ответы на вопросы на собеседование Сериализация.

  • Что такое сериализация?

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

  • Как исключить поля из сериализации?

Для того чтоб исключить поля из сериализуемого потока, необходимо пометить поле модификатором transient.

  • transient что значит?

Свойства класса, помеченные модификатором transient, не сериализуются. Обычно в таких полях хранится промежуточное состояние объекта, которое, к примеру, проще вычислить, чем сериализовать, а затем десериализавать. Другой пример такого поля -
ссылка на экземпляр объекта, который не требует сериализации или не может быть сериализован.

  • Как изменить стандартное поведение сериализации/десериализации?

В большинстве случаев мы не определяем поведение вручную, а полагаемся на стандартную реализацию, и очень не удобно постоянно переопределять какие-то методы сериализации + постоянно следить за добавлением новых полей, добавлять их в методы. Ну и специально для этих целей есть Externalizable.
Тем не менее, мы знаем, что можно изменить стандартное поведение сериализации предопределив и поместив в свои файлы классов два метода:
Обратите внимание, что оба метода объявлены как private, поскольку это гарантирует что методы не будут переопределены или перезагружены. Весь фокус в том, что виртуальная машина при вызове соответствующего метода автоматически проверяет, не были ли они объявлены в классе объекта. Виртуальная машина в любое время может вызвать private методы вашего класса, но другие объекты этого сделать не смогут. Таким образом обеспечивается целостность класса и нормальная работа протокол сериализации.

  • Вы создали класс, чей суперкласс сериализуемый, но при этом вы не хотите чтобы ваш класс был сериализуемым, как остановить сериализацию?

Вы не можете "разреализовать" интерфейс, поэтому если суперкласс реализует Serializable, то и созданный вами новый класс также будет реализовать его. Чтобы остановить автоматическую сериализацию вы можете применить private методы для создания исключительной ситуации NotSerializableException. Вот как это можно сделать:
Любая попытка записать или прочитать этот объект теперь приведет к возникновению исключительной ситуации. Запомните, если методы объявлены как private, никто не сможет модифицировать ваш код не изменяя исходный код класса. Java не позволяет переопределять такие методы.

  • Как создать собственный протокол сериализации?

Вместо реализации интерфейса Serializable, вы можете реализовать интерфейс Externalizable, который содержит два метода:
Для создания собственного протокола нужно просто переопределить эти два метода. В отличие от двух других вариантов сериализации, здесь ничего не делается автоматически. Протокол полностью в ваших руках. Хотя это и наиболее сложный способ, при этом он наиболее контролируемый.

  • Какая роль поля serialVersionUID в сериализации?

Поле private static final long serialVersionUID содержит уникальный идентификатор версии сериализованного класса. Оно вычисляется по содержимому класса - полям, их порядку объявления, методам, их порядку объявления. Соответственно, при любом изменении в классе это поле поменяет свое значение.
Это поле записывается в поток при сериализации класса. Кстати, это, пожалуй, единственный известный случай, когда static-поле сериализуется.

  • В чем проблема сериализации Singleton-ов?

Проблема в том что после десериализации мы получим другой объект. Таким образом, сериализация дает возможность создать Singleton еще раз, что не совсем не нужно. Конечно можно запретить сериализовать Singleton-ы, но это, фактически, уход от проблемы, а не ее решение.
Решение же заключается в следующем. В классе определяется метод со следующей сигнатурой
Модификатор доступа может быть private, protected и по умолчанию (default). Можно, наверное, сделать его и public, но смысла я в этом не вижу. Назначение этого метода - возвращать замещающий объект вместо объекта, на котором он вызван.

Рассказать друзьям:

0 коментарі :

Отправить комментарий