Spec-Zone.ru › OpenJDK 8

Интерфейс Serializable

Все известные подинтерфейсы:
AdapterActivator, Attribute, Attribute, Attributes, BindingIterator, CertPathValidatorException.Reason, ClientRequestInfo, ClientRequestInterceptor, Codec, CodecFactory, Control, Current, Current, Current, CustomValue, DataInputStream, DataOutputStream, Descriptor, DHPrivateKey, DHPublicKey, DocAttribute, DomainManager, DSAPrivateKey, DSAPublicKey, DynAny, DynAnyFactory, DynArray, DynEnum, DynFixed, DynSequence, DynStruct, DynUnion, DynValue, DynValueBox, DynValueCommon, ECPrivateKey, ECPublicKey, ExtendedRequest, ExtendedResponse, Externalizable, IdAssignmentPolicy, IDLEntity, IDLType, IdUniquenessPolicy, ImplicitActivationPolicy, Interceptor, IORInfo, IORInterceptor, IORInterceptor_3_0, IRObject, Ключ, LifespanPolicy, Имя, NamingContext, NamingContextExt, NotificationFilter, ObjectReferenceFactory, ObjectReferenceTemplate, ORBInitializer, ORBInitInfo, PBEKey, POA, POAManager, Policy, PolicyFactory, PrintJobAttribute, PrintRequestAttribute, PrintServiceAttribute, PrivateKey, PublicKey, QueryExp, RelationType, RemoteRef, RequestInfo, RequestProcessingPolicy, RSAMultiPrimePrivateCrtKey, RSAPrivateCrtKey, RSAPrivateKey, RSAPublicKey, RunTime, SecretKey, ServantActivator, ServantLocator, ServantManager, ServantRetentionPolicy, ServerRef, ServerRequestInfo, ServerRequestInterceptor, StreamableValue, SupportedValuesAttribute, ThreadPolicy, UnsolicitedNotification, ValueBase, ValueExp

public interface Serializable

Сериализуемость класса обеспечивается реализацией интерфейса java.io.Serializable. Классы, не реализующие этот интерфейс, не будут сериализованы или десериализованы. Все подтипы сериализуемого класса сами являются сериализуемыми. Интерфейс сериализации не имеет методов или полей и служит только для определения семантики сериализуемости.

Чтобы разрешить сериализацию подтипов несериализуемых классов, подтип может взять на себя ответственность за сохранение и восстановление состояния общедоступных, защищенных и (если доступны) полей пакета супертипа. Подтип может взять на себя эту ответственность только в том случае, если у расширяемого класса есть доступный конструктор без аргументов для инициализации состояния класса. Объявление класса Serializable в этом случае является ошибкой. Ошибка будет обнаружена во время выполнения.

Во время десериализации поля несериализуемых классов будут инициализированы с помощью публичного или защищенного конструктора без аргументов класса. Конструктор без аргументов должен быть доступен для подкласса, который является сериализуемым. Поля сериализуемых подклассов будут восстановлены из потока.

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

Классы, требующие специальной обработки во время сериализации и десериализации, должны реализовывать специальные методы с точными сигнатурами:

private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 private void readObjectNoData()
     throws ObjectStreamException;

Метод writeObject отвечает за запись состояния объекта для его конкретного класса, чтобы соответствующий метод readObject мог его восстановить. Стандартный механизм сохранения полей объекта может быть вызван с помощью вызова out.defaultWriteObject. Методу не нужно беспокоиться о состоянии, принадлежащем его суперклассам или подклассам. Состояние сохраняется путем записи отдельных полей в ObjectOutputStream с помощью метода writeObject или с помощью методов для примитивных типов данных, поддерживаемых DataOutput.

Метод readObject отвечает за чтение из потока и восстановление полей класса. Он может вызвать in.defaultReadObject для вызова стандартного механизма восстановления нестатических и непеременных полей объекта. Метод defaultReadObject использует информацию из потока для присвоения полям объекта, сохраненного в потоке, соответствующим именованным полям в текущем объекте. Это обрабатывает случай, когда класс эволюционировал, добавив новые поля. Методу не нужно беспокоиться о состоянии, принадлежащем его суперклассам или подклассам. Состояние сохраняется путем записи отдельных полей в ObjectOutputStream с помощью метода writeObject или с помощью методов для примитивных типов данных, поддерживаемых DataOutput.

Метод readObjectNoData отвечает за инициализацию состояния объекта для его конкретного класса в случае, если поток сериализации не указывает данный класс как суперкласс десериализуемого объекта. Это может произойти в тех случаях, когда получающая сторона использует другую версию класса десериализованной инстанции, чем отправляющая сторона, и версия получателя расширяет классы, которые не расширяются версией отправителя. Это также может произойти, если поток сериализации был взломан; следовательно, readObjectNoData полезен для правильной инициализации десериализованных объектов, несмотря на «враждебный» или неполный исходный поток.

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

ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;

Этот метод writeReplace вызывается механизмом сериализации, если он существует и доступен из метода, определенного в классе сериализуемого объекта. Таким образом, метод может иметь закрытый, защищенный и пакетный доступ. Доступ к этому методу подклассам соответствует правилам доступа Java.

Классы, которым нужно назначить замену при чтении экземпляра из потока, должны реализовать этот специальный метод с точной сигнатурой.

ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;

Метод readResolve следует тем же правилам вызова и доступа, что и writeReplace.

Сериализация runtime связывает с каждым сериализуемым классом номер версии, называемый serialVersionUID, который используется во время десериализации для проверки того, что отправитель и получатель сериализованного объекта загрузили классы для этого объекта, совместимые с точки зрения сериализации. Если получатель загрузил класс для объекта, у которого другой serialVersionUID, чем у соответствующего класса отправителя, то десериализация приведет к InvalidClassException. Сериализуемый класс может явно объявить свой serialVersionUID, объявив поле, названное "serialVersionUID", которое должно быть статическим, финальным и типа long:

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
Если сериализуемый класс не объявляет явно serialVersionUID, то механизм сериализации вычислит значение serialVersionUID по умолчанию для этого класса на основе различных аспектов класса, как описано в спецификации Java(TM) Object Serialization. Однако настоятельно рекомендуется, чтобы все сериализуемые классы явно объявляли значения serialVersionUID, поскольку вычисление serialVersionUID по умолчанию сильно зависит от деталей класса, которые могут меняться в зависимости от реализации компилятора, и, таким образом, могут привести к неожиданным InvalidClassException во время десериализации. Поэтому для гарантии согласованного значения serialVersionUID в разных реализациях компилятора Java сериализуемый класс должен объявить явное значение serialVersionUID. Также настоятельно рекомендуется, чтобы явные объявления serialVersionUID использовали модификатор private там, где это возможно, поскольку такие объявления применяются только к объявляемому классу — поля serialVersionUID не пригодны в качестве наследуемых членов. Классы массивов не могут объявить явное serialVersionUID, поэтому они всегда имеют значение по умолчанию, вычисленное, но требование соответствия значений serialVersionUID отменяется для классов массивов.
С момента:
JDK1.1
См. также:
ObjectOutputStream, ObjectInputStream, ObjectOutput, ObjectInput, Externalizable

© 1993, 2020, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API