JavaCore5.2: Serialization Flashcards

1
Q

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

A

“Сериализация это процесс сохранения состояния объекта в последовательность байт;

Реализована через интерфейс - маркер Serializable. “

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Опишите процесс сериализации/десериализации с использованием Serializable.

A

“1) Класс объекта должен реализовывать интерфейс Serializable
2) Создать поток ObjectOutputStream (oos), который записывает объект в переданный OutputStream.
3) Записать в поток: oos.writeObject(Object):
- запись в поток метаданных о классе, ассоциированном с объектом (имя класса, идентификатор SerialVersionUID, идентификаторы полей класса);
- рекурсивную запись в поток описания суперклассов до класса java.lang.Object (не включительно);
- запись примитивных значений полей сериализуемого экземпляра, начиная с полей самого верхнего суперкласса;
- рекурсивную запись объектов, которые являются полями сериализуемого объекта.
4) Сделать oos.flush() и oos.close()”

Для выполнения десериализации под объект выделяется память, после чего его поля заполняются значениями из потока. Конструктор объекта при этом не вызывается. Однако при десериализации будет вызван конструктор без параметров родительского несериализуемого класса, а его отсутствие повлечёт ошибку десериализации.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

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

A

1) Использовать интерфейс Externalizable:
Переопределить методы
` writeExternal(ObjectOutput out) throws IOException readExternal(ObjectInput in) throws IOException, ClassNotFoundException`

2) переопределить методы:
- writeObject(ObjectOutputStream )
- readObject()
- writeReplace()
- readResolve()

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Как не сериализовать поле?

A

1) Добавить к полю модификатор transient. В таком случае после восстановления его значение будет null.

2) Сделать поле static. Значения статических полей автоматически не сохраняются.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Будет ли сериализовано final поле?

A

Поля с модификатором final сериализуются как и обычные. За одним исключением – их невозможно десериализовать при использовании Externalizable, поскольку final-поля должны быть инициализированы в конструкторе, а после этого в readExternal изменить значение этого поля будет невозможно. Соответственно, если необходимо сериализовать объект с final-полем неоходимо использовать только стандартную сериализацию.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Какая роль поля serialVersionUID в сериализации? как оно вычисляется? Что будет, если мы не укажем его явно?

A
  • Поле private static final long serialVersionUID содержит уникальный идентификатор версии сериализованного класса. - Оно вычисляется по содержимому класса - полям, их порядку объявления, методам, их порядку объявления. Соответственно, при любом изменении в классе это поле поменяет свое значение.
    Если мы не объявляем его явно, Java делает это за нас.”
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Когда стоит изменять значение поля serialVersionUID?

A

serialVersionUID нужно изменять при внесении в класс несовместимых изменений, например при удалении какого-либо его атрибута.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Какие существуют способы контроля за значениями десериализованного объекта?

A

можно использовать интерфейс ObjectInputValidation с переопределением метода validateObject(), вызвав его после десериализации:
~~~
@Override
public void validateObject()
throws InvalidObjectException {
if ((age < 39) || (age > 60))
throw new InvalidObjectException(“Invalid age”);
}
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

В чем проблема сериализации Singleton и как ее решить?

A
  • Проблема в том что после десериализации мы получим другой объект
  • Решить можно с помощью метода readResolve(), он подменяет десериализованный объект но существующий объект.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Как не допустить сериализацию?

A

можно переопределить private методы для создания исключительной ситуации NotSerializableException.
~~~
private void writeObject(ObjectOutputStream out) throws IOException {
throw new NotSerializableException();
}

private void readObject(ObjectInputStream in) throws IOException {
throw new NotSerializableException();
}
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

3 способа клонирования объектов.

A
  1. С использованием интерфейса Cloneable:
    подразумевает, что вы будете использовать механизм так называемого «поверхностного клонирования» и сами позаботитесь о клонировании полей-объектов. Метод clone() в родительском классе Object является protected, поэтому требуется переопределение его с объявлением как public. Он возвращает экземпляр объекта с копированными полями-примитивами и ссылками. И получается что у оригинала и его клона поля-ссылки указывают на одни и те же объекты.
  2. С использованием конструктора клонирования объекта;
    В классе описывается конструктор, который принимает объект этого же класса и инициализирует значениями его полей поля нового объекта. Считается наиболее предпочтительным.
  3. С использованием сериализации.
    Он заключается в сохранении объекта в поток байтов с последующей эксгумацией его от туда.”
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Почему метод clone() объявлен в классе Object, а не в интерфейсе Cloneable?

A

Метод clone() объявлен в классе Object с сигнатурой native, чтобы обеспечить доступ к стандартному механизму “поверхностного копирования” объектов (копируются значения всех полей, включая ссылки на сторонние объекты); он объявлен, как protected, чтобы нельзя было вызвать этот метод у не переопределивших его объектов.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly