Интерфейс Serializable
- Все известные подинтерфейсы:
AsymmetricKey, 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 нельзя; ошибка будет обнаружена во время выполнения. Сериализуемый подтип может взять на себя ответственность за сохранение и восстановление общедоступных, защищённых и (если они доступны) пакетных полей несериализуемого суперкласса. Подробное описание процесса десериализации, включая обработку сериализуемых и несериализуемых классов, см. в разделе 3.1 Спецификации сериализации объектов Java.
При обходе графа может встретиться объект, не поддерживающий интерфейс 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 вызывается при сериализации, если этот метод существует и доступен из метода, определённого в классе сериализуемого объекта. Таким образом, метод может иметь модификатор доступа private, protected или доступ на уровне пакета. Доступ к этому методу из подкласса определяется правилами доступа Java.
Классы, которым требуется указать объект-замену при чтении экземпляра из потока, должны реализовать этот специальный метод с точной сигнатурой.
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
Метод readResolve подчиняется тем же правилам вызова и доступа, что и writeReplace.
Все типы перечислений являются сериализуемыми и при сериализации и десериализации обрабатываются согласно Спецификации сериализации объектов Java. Все объявления специальных методов обработки, рассмотренных выше, для типов перечислений игнорируются.
Классы-записи могут реализовывать Serializable и обрабатываются согласно Спецификации сериализации объектов Java, разделу 1.13 «Сериализация записей». Все объявления специальных методов обработки, рассмотренных выше, для типов-записей игнорируются.
Среда выполнения сериализации связывает с каждым сериализуемым классом номер версии, называемый serialVersionUID. Он используется при десериализации, чтобы проверить, совместимы ли с точки зрения сериализации классы, загруженные отправителем и получателем сериализованного объекта. Если получатель загрузил для объекта класс, 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, 2025, 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/25/docs/api/java.base/java/io/Serializable.html