Интерфейс 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,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.io.Serializable классом.
Предупреждение: Десериализация недоверенных данных по своей природе опасна и должна быть избегаема. Недоверенные данные должны быть тщательно проверены в соответствии с разделом «Сериализация и десериализация» руководства по защите кода Java SE. Руководство по защите кода для Java SE. Фильтрация сериализации описывает лучшие практики для защитного использования фильтров сериализации.
Классы, которые не реализуют этот интерфейс, не будут сериализованы или десериализованы. Все подклассы сериализуемого класса сами являются сериализуемыми. Интерфейс сериализации не имеет методов или полей и служит только для идентификации семантики сериализации.Чтобы позволить подклассам несериализуемых классов быть сериализованными, подкласс может взять на себя ответственность за сохранение и восстановление состояния общедоступных, защищенных и (если доступно) пакетных полей супертипа. Подкласс может взять на себя эту ответственность только в том случае, если у класса, от которого он расширяется, есть доступный конструктор без аргументов для инициализации состояния класса. Объявление класса 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 использует информацию в потоке для присвоения полям объекта, сохраненного в потоке, соответствующих именованных полей в текущем объекте. Это обрабатывает случай, когда класс эволюционировал, добавив новые поля. Методу не нужно беспокоиться о состоянии, принадлежащем его суперклассам или подклассам. Состояние восстанавливается путем чтения данных из ObjectInputStream для отдельных полей и присвоения значений соответствующим полям объекта. Чтение примитивных типов данных поддерживается DataInput.
Метод readObjectNoData отвечает за инициализацию состояния объекта для его конкретного класса в случае, если поток сериализации не указывает данный класс в качестве суперкласса десериализуемого объекта. Это может произойти в случаях, когда принимающая сторона использует другую версию класса десериализованной инстанции, чем отправляющая сторона, и версия получателя расширяет классы, которые не расширяются версией отправителя. Это также может произойти, если поток сериализации был взломан; следовательно, readObjectNoData полезен для правильной инициализации десериализованных объектов несмотря на «враждебный» или неполный исходный поток.
Сериализуемые классы, которым нужно указать альтернативный объект для использования при записи объекта в поток, должны реализовать этот специальный метод с точной сигнатурой:
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
Этот метод writeReplace вызывается сериализацией, если метод существует и его можно будет вызвать из метода, определенного в классе сериализуемого объекта. Таким образом, метод может иметь доступ private, protected и package-private. Доступ подклассов к этому методу соответствует правилам доступа Java.
Классы, которым нужно указать замену при чтении экземпляра из потока, должны реализовать этот специальный метод с точной сигнатурой.
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
Метод readResolve следует тем же правилам вызова и доступа, что и writeReplace.
Сериализационный модуль связывает с каждым сериализуемым классом номер версии, называемый serialVersionUID, который используется во время десериализации для проверки того, что отправитель и получатель сериализованного объекта загрузили классы для этого объекта, совместимые с точки зрения сериализации. Если получатель загрузил класс для объекта, у которого есть другой serialVersionUID, чем у соответствующего класса отправителя, то десериализация приведет к исключению InvalidClassException. Сериализуемый класс может явно объявить свой собственный serialVersionUID, объявив поле с именем "serialVersionUID", которое должно быть статическим, конечным и типа long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;Если сериализуемый класс не объявляет serialVersionUID явно, то модуль сериализации вычислит значение serialVersionUID по умолчанию для этого класса на основе различных аспектов класса, как описано в спецификации сериализации объектов Java(TM). Однако настоятельно рекомендуется, чтобы все сериализуемые классы явно объявляли значения serialVersionUID, так как вычисление значения serialVersionUID по умолчанию сильно зависит от деталей класса, которые могут меняться в зависимости от реализаций компиляторов, и, таким образом, может привести к непредвиденным
InvalidClassException во время десериализации. Поэтому для гарантии согласованного значения serialVersionUID в различных реализациях компилятора Java сериализуемый класс должен явно объявить значение serialVersionUID. Также настоятельно рекомендуется, чтобы явные объявления serialVersionUID использовали модификатор private, поскольку такие объявления применяются только к непосредственно объявляемому классу - поля serialVersionUID не являются полезными как наследуемые члены. Классы массивов не могут явно объявить serialVersionUID, поэтому они всегда имеют значение по умолчанию, но требование соответствия значений serialVersionUID отменяется для классов массивов.- С:
- 1.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.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/Serializable.html