Интерфейс Serializable
- Все известные подинтерфейсы:
-
Attribute,Attribute,Attributes,CertPathValidatorException.Reason,Connector.Argument,Connector.BooleanArgument,Connector.IntegerArgument,Connector.SelectedArgument,Connector.StringArgument,Control,Descriptor,DHPrivateKey,DHPublicKey,DocAttribute,DSAPrivateKey,DSAPublicKey,ECPrivateKey,ECPublicKey,EdECPrivateKey,EdECPublicKey,ExtendedRequest,ExtendedResponse,Externalizable,Key,Name,NotificationFilter,PBEKey,PrintJobAttribute,PrintRequestAttribute,PrintServiceAttribute,PrivateKey,PublicKey,QueryExp,RelationType,RemoteRef,RSAMultiPrimePrivateCrtKey,RSAPrivateCrtKey,RSAPrivateKey,RSAPublicKey,SecretKey,ServerRef,SupportedValuesAttribute,UnsolicitedNotification,ValueExp,XECPrivateKey,XECPublicKey
public interface Serializable
Предупреждение: Десериализация недоверенных данных по своей природе опасна и должна быть избегана. Недоверенные данные должны быть тщательно проверены в соответствии с разделом «Сериализация и десериализация» в Рекомендациях по защищенному программированию для Java SE. Фильтрация сериализации описывает лучшие практики для защищенного использования фильтров сериализации.
Классы, которые не реализуют этот интерфейс, не будут сериализовать или десериализовать своё состояние. Все подклассы сериализуемого класса сами по себе сериализуемы. Интерфейс сериализации не имеет методов или полей и служит только для идентификации семантики сериализуемости.Субтипы несериализуемых классов могут быть сериализованы и десериализованы. Во время сериализации данные для полей несериализуемых суперклассов не будут записываться. Во время десериализации поля несериализуемых суперклассов будут инициализированы с помощью конструктора без аргументов первого (нижнего) несериализуемого суперкласса. Этот конструктор должен быть доступен для подкласса, который десериализуется. Объявление класса Serializable является ошибкой, если это не так; ошибка будет обнаружена во время выполнения. Сериализуемый подтип может взять на себя ответственность за сохранение и восстановление состояния публичных, защищенных и (если доступны) полей доступа к пакетам несериализуемого супертипа. См. Спецификацию сериализации Java Object, раздел 3.1, для подробной спецификации процесса десериализации, включая обработку сериализуемых и несериализуемых классов.
При обходе графа может быть обнаружен объект, не поддерживающий интерфейс 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 использует информацию в потоке для назначения полей объекта, сохраненного в потоке, соответствующим именованным полям в текущем объекте. Это обрабатывает случай, когда класс эволюционировал, добавив новые поля. Метод не должен беспокоиться о состоянии, принадлежащем его суперклассам или подклассам. Состояние восстанавливается путем чтения данных из ObjectInputStream для отдельных полей и выполнения присваиваний соответствующим полям объекта. Чтение примитивных типов данных поддерживается DataInput.
Метод readObjectNoData отвечает за инициализацию состояния объекта для его конкретного класса в случае, если поток сериализации не указывает данный класс как суперкласс десериализуемого объекта. Это может произойти в тех случаях, когда принимающая сторона использует другую версию класса десериализованной инстанции, чем отправляющая сторона, и версия получателя расширяет классы, которые не расширяются версией отправителя. Это также может произойти, если поток сериализации был изменен; таким образом, readObjectNoData полезен для правильной инициализации десериализованных объектов, несмотря на «враждебный» или неполный исходный поток.
Сериализуемые классы, которым нужно указать альтернативный объект для использования при записи объекта в поток, должны реализовать этот специальный метод с точной сигнатурой:
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
Этот метод writeReplace вызывается сериализацией, если метод существует и его можно вызвать из метода, определенного в классе сериализуемого объекта. Таким образом, метод может иметь закрытый, защищенный и пакетный доступ. Доступ к этому методу из подкласса следует правилам доступа Java.
Классы, которые должны указать замену при чтении экземпляра из потока, должны реализовать этот специальный метод с точной сигнатурой.
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
Этот метод readResolve следует тем же правилам вызова и доступа, что и writeReplace.
Все типы перечислений являются сериализуемыми и обрабатываются в соответствии с Спецификацией сериализации Java Object во время сериализации и десериализации. Любые объявления специальных методов обработки, обсуждавшиеся выше, игнорируются для типов перечислений.
Классы записей могут реализовывать Serializable и обрабатываются в соответствии с Спецификацией сериализации Java Object, раздел 1.13, «Сериализация записей». Любые объявления специальных методов обработки, обсуждавшиеся выше, игнорируются для типов записей.
Сериализующий механизм связывает с каждым сериализуемым классом номер версии, называемый serialVersionUID, который используется во время десериализации для проверки того, что отправитель и получатель сериализованного объекта загрузили классы для этого объекта, совместимые с точки зрения сериализации. Если получатель загрузил класс объекта, у которого другой serialVersionUID, чем у соответствующего класса отправителя, десериализация приведет к InvalidClassException. Сериализуемый класс может явно объявить свой serialVersionUID, объявив поле с именем "serialVersionUID" , которое должно быть статическим, финальным и типа long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;Если сериализуемый класс не объявляет явно serialVersionUID, то сериализующий механизм рассчитает значение serialVersionUID по умолчанию для этого класса на основе различных аспектов класса, как описано в Спецификации сериализации Java Object. Эта спецификация определяет serialVersionUID типа перечисления как 0L. Однако настоятельно рекомендуется, чтобы все сериализуемые классы, кроме типов перечислений, явно объявляли значения serialVersionUID, так как вычисление serialVersionUID по умолчанию сильно зависит от деталей класса, которые могут варьироваться в зависимости от реализации компилятора, и может привести к непредвиденным
InvalidClassException при десериализации. Поэтому, чтобы гарантировать постоянное значение serialVersionUID в различных реализациях компилятора Java, сериализуемый класс должен объявить явное значение serialVersionUID. Также настоятельно рекомендуется, чтобы явные объявления serialVersionUID использовали модификатор private по возможности, поскольку такие объявления применяются только к непосредственно объявляемому классу; поля serialVersionUID не являются полезными как унаследованные члены. Классы массивов не могут объявить явный serialVersionUID, поэтому они всегда имеют значение по умолчанию, вычисленное, но требование соответствия значений serialVersionUID отменяется для классов массивов.
© 1993, 2021, 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.
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Serializable.html