Интерфейс 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, раздел 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.
Типы перечислений (Enum) являются сериализуемыми и обрабатываются согласно Спецификации сериализации объектов Java во время сериализации и десериализации. Любые объявления специальных методов обработки, обсуждаемых выше, игнорируются для типов перечислений.
Классы записей (Record) могут реализовать Serializable и получают обработку, определенную в Спецификации сериализации объектов Java, раздел 1.13, "Сериализация записей". Любые объявления специальных методов обработки, обсуждаемых выше, игнорируются для типов записей.
Сериализующий движок связывает с каждым сериализуемым классом номер версии, называемый serialVersionUID, который используется во время десериализации для проверки того, что отправитель и получатель сериализованного объекта загрузили классы для этого объекта, которые совместимы с точки зрения сериализации. Если получатель загрузил класс для объекта с другим serialVersionUID, чем у соответствующего класса отправителя, то десериализация приведет к InvalidClassException. Сериализуемый класс может явно объявить свой serialVersionUID, объявив поле с именем "serialVersionUID", которое должно быть статическим, конечным и типа long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;Если сериализуемый класс не объявляет явно serialVersionUID, тогда сериализующий движок вычислит значение serialVersionUID по умолчанию для этого класса на основе различных аспектов класса, как описано в Спецификации сериализации объектов Java. Эта спецификация определяет serialVersionUID типа перечисления как 0L. Однако, настоятельно рекомендуется, чтобы все сериализуемые классы, кроме типов перечислений, явно объявляли значения serialVersionUID, поскольку вычисление serialVersionUID по умолчанию сильно зависит от деталей класса, которые могут варьироваться в зависимости от реализации компилятора, и в результате может привести к неожиданным
InvalidClassException во время десериализации. Поэтому, чтобы гарантировать постоянное значение serialVersionUID в различных реализациях компилятора Java, сериализуемый класс должен объявить явное значение serialVersionUID. Также настоятельно рекомендуется, чтобы явные объявления serialVersionUID использовали модификатор private где это возможно, поскольку такие объявления применяются только к непосредственно объявляющему классу — поля serialVersionUID не являются полезными как унаследованные члены. Классы массивов не могут явно объявлять serialVersionUID, поэтому они всегда имеют значение по умолчанию, вычисленное, но требование к соответствию значений serialVersionUID отменяется для классов массивов.- С момента:
- 1.1
- Внешние спецификации
- См. также:
© 1993, 2023, 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/21/docs/api/java.base/java/io/Serializable.html