Главная страница
Навигация по странице:

  • Какое влияние оказывают на сериализуемость модификаторы полей static и final (Externalizable)

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

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

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

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

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

  • Ревью 5. Что такое потоки вводавывода Как это реализовано в Java 3 Классынадстройки потоков вводавывода 4


    Скачать 110.73 Kb.
    НазваниеЧто такое потоки вводавывода Как это реализовано в Java 3 Классынадстройки потоков вводавывода 4
    АнкорРевью 5
    Дата24.12.2022
    Размер110.73 Kb.
    Формат файлаdocx
    Имя файлаРевью 5.docx
    ТипДокументы
    #861326
    страница10 из 13
    1   ...   5   6   7   8   9   10   11   12   13

    Что обозначает ключевое слово transient?


    Поля класса, помеченные модификатором transient, не сериализуются.

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

    Какое влияние оказывают на сериализуемость модификаторы полей static и final (Externalizable)


    При стандартной сериализации поля, имеющие модификатор static, не сериализуются. Соответственно, после десериализации это поле значения не меняет. При использовании реализации Externalizable сериализовать и десериализовать статическое поле можно, но не рекомендуется этого делать, т.к. это может сопровождаться трудноуловимыми ошибками.

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

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


    Чтобы не допустить автоматическую сериализацию можно переопределить private методы для создания исключительной ситуации NotSerializableException.

    private void writeObject(ObjectOutputStream out) throws IOException {

    throw new NotSerializableException();

    }

    private void readObject(ObjectInputStream in) throws IOException {

    throw new NotSerializableException();

    }

    Любая попытка записать или прочитать этот объект теперь приведет к возникновению исключительной ситуации.

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


    Для создания собственного протокола сериализации достаточно реализовать интерфейс Externalizable, который содержит два метода:

    public void writeExternal(ObjectOutput out) throws IOException;

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;

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


    serialVersionUID используется для указания версии сериализованных данных.

    Когда мы не объявляем serialVersionUID в нашем классе явно, среда выполнения Java делает это за нас, но этот процесс чувствителен ко многим метаданным класса включая количество полей, тип полей, модификаторы доступа полей, интерфейсов, которые реализованы в классе и пр.

    Рекомендуется явно объявлять serialVersionUID т.к. при добавлении, удалении атрибутов класса динамически сгенерированное значение может измениться и в момент выполнения будет выброшено исключение InvalidClassException.

    private static final long serialVersionUID = 20161013L;

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


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

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


    Проблема в том что после десериализации мы получим другой объект. Таким образом, сериализация дает возможность создать Singleton еще раз, что недопустимо. Существует два способа избежать этого:

    явный запрет сериализации.

    определение метода с сигнатурой (default/public/private/protected/) Object readResolve() throws ObjectStreamException, назначением которого станет возврат замещающего объекта вместо объекта, на котором он вызван.

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


    Если есть необходимость выполнения контроля за значениями десериализованного объекта, то можно использовать интерфейс ObjectInputValidation с переопределением метода validateObject().

    // Если вызвать метод validateObject() после десериализации объекта, то будет вызвано исключение InvalidObjectException при значении возраста за пределами 39...60.

    public class Person implements java.io.Serializable,

    java.io.ObjectInputValidation {

    ...

    @Override

    public void validateObject() throws InvalidObjectException {

    if ((age < 39) || (age > 60))

    throw new InvalidObjectException("Invalid age");
    Так же существуют способы подписывания и шифрования, позволяющие убедиться, что данные не были изменены:

    с помощью описания логики в writeObject() и readObject().

    поместить в оберточный класс javax.crypto.SealedObject и/или java.security.SignedObject. Данные классы являются сериализуемыми, поэтому при оборачивании объекта в SealedObject создается подобие «подарочной упаковки» вокруг исходного объекта. Для шифрования необходимо создать симметричный ключ, управление которым должно осуществляться отдельно. Аналогично, для проверки данных можно использовать класс SignedObject, для работы с которым также нужен симметричный ключ, управляемый отдельно.
    1   ...   5   6   7   8   9   10   11   12   13


    написать администратору сайта