2012-04-20 7 views
2

Как идентификатор сериализации хранится в экземпляре объекта?Сериализация версии uid в Java

Идентификатор сериализации, который мы объявляем в Java, является статическим полем, а статические поля не сериализуются.

Должен быть способ хранения статического конечного поля. Как java это делает?

ответ

2

Если вы посмотрите в java.io.ObjectStreamClass, вы увидите, что на самом деле он сериализуется. Следующий метод:

java.io.ObjectOutputStream.writeClassDescriptor(ObjectStreamClass)

вызывает метод, который вызывает следующий метод:

java.io.ObjectStreamClass.getSerialVersionUID()

Какие либо вычисляет serialVersionUID или использует один объявленный в классе и нашли ранее в вызове по следующему методу:

java.io.ObjectStreamClass.getDeclaredSUID(Class)

Так что кажется, что это статическое поле является исключением из правила, что статические поля не сериализуются.

Как читать описано here.

3

serialVersionUID не хранится в экземпляре «сериализованного» объекта, так как это статическое поле (оно является частью класса, а не части объекта).

Таким образом, это stored в скомпилированном байт-коде, если оно фактически определено, в противном случае оно вычисляется. В словах java specification:

Если класс определил serialVersionUID, он извлекается из класса. Если serialVersionUID не определен классом, он вычисляется из определения класса на виртуальной машине. Если> указанный класс не является сериализуемым или внешним, возвращается null.

В Stream Unique Identifiers section объясняется алгоритм для таких вычислений.

Этот параграф примечателен (поэтому IDE обычно показывают предупреждение, когда класс, реализующий Serializable, явно не определил serialVersionUID).

Примечание: Настоятельно рекомендуется, чтобы все сериализуемые классы явно объявлять serialVersionUID значения, так как serialVersionUID вычисления по умолчанию очень чувствительно к деталям класса, которые могут варьироваться в зависимости от реализации компилятора, и таким образом, могут привести к в неожиданных конфликтах serialVersionUID во время десериализации, что приводит к сбою десериализации.

+0

@downvoter: Можете ли вы прокомментировать свой downvote? – jalopaba

+0

«относительный» нижний план. Должен был удостовериться, что лучший ответ Джири идет сверху (иначе не было бы ниспроверено). Вы полностью игнорируете суть вопроса, каким образом JVM знает версию сериализованных данных (если UID для нее не записывается в поток, что, конечно, есть, хотя это статическое поле). – Thilo

0

serialVersionUID - это специальное поле, используемое во время выполнения сериализации.Все это описано в Java Doc для java.lang.Serializable

2

UID серийной версии не хранится в объектах; это статическое поле, поэтому оно хранится в определении класса. Случается, что когда вы сериализуете объект, информация о его классе также должна быть сохранена; в противном случае не было бы способа un-serialize объекта. Информация, хранящаяся в классе, включает его имя и его UID последовательной версии.

Вы можете прочитать весь протокол здесь: http://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html

В общем, запись для нового объекта именно:

newObject: 
    TC_OBJECT classDesc newHandle classdata[] 

Здесь classDesc является дескриптор класса, который может быть либо декларация нового класса, нулевой ссылки или ссылки на ранее объявленного класса:

classDesc: 
    newClassDesc 
    nullReference 
    (ClassDesc)prevObject 

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

newClassDesc: 
    TC_CLASSDESC className serialVersionUID newHandle classDescInfo 
Смежные вопросы