Как обеспечить согласованность перечислений в сериализации Java? - PullRequest
16 голосов
/ 17 июня 2010

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

Однако, что происходит, когда я сериализую поля значений enum?Есть ли способ убедиться, что типом enum не манипулировали между сериализацией и десериализацией?

Предположим, что у меня есть enum, такой как OperationResult {SUCCESS, FAIL}, и поле с именем "result" в объекте, которыйсериализуется.Как я могу гарантировать, что при десериализации объекта этот результат все еще верен, даже если кто-то злонамеренно поменял их местами?(Предположим, что перечисление объявлено в другом месте как статическое перечисление)

Мне интересно из любопытства - я использую аутентификацию на уровне jar для предотвращения манипуляций.

Ответы [ 2 ]

22 голосов
/ 17 июня 2010

From: http://www.theserverside.com/news/thread.tss?thread_id=50190#265205

Разработчики функции enum решили, что для создания новых объектов enum во время выполнения не существует смысла.Они очень старались не допустить этого.

Следовательно, похоже, что перечисляемые объекты не могут быть сериализованы и десериализованы полностью.Кроме того, из http://java.sun.com/javase/6/docs/platform/serialization/spec/serial-arch.html#6469:

константы Enum сериализуются иначе, чем обычные сериализуемые или экстернализуемые объекты.Сериализованная форма константы перечисления состоит исключительно из ее имени;Значения полей константы отсутствуют в форме.Чтобы сериализовать константу перечисления, ObjectOutputStream записывает значение, возвращаемое методом имени константы перечисления.Чтобы десериализовать константу перечисления, ObjectInputStream считывает имя константы из потока;десериализованная константа затем получается путем вызова метода java.lang.Enum.valueOf, передавая тип перечисления константы вместе с полученным именем константы в качестве аргументов.Как и другие сериализуемые или экстернализуемые объекты, константы перечисления могут функционировать как цели обратных ссылок, появляющихся впоследствии в потоке сериализации.

Процесс, с помощью которого сериализуются константы перечисления, не может быть настроен: любой специфичный для класса writeObject readObject,Методы readObjectNoData, writeReplace и readResolve, определенные типами enum, игнорируются при сериализации и десериализации.Аналогичным образом любые объявления полей serialPersistentFields или serialVersionUID также игнорируются - все типы перечислений имеют фиксированный serialVersionUID, равный 0L.Документирование сериализуемых полей и данных для перечислимых типов не требуется, поскольку нет различий в типе отправляемых данных.

5 голосов
/ 17 июня 2010

Перечисления заменяются на чтение во время десериализации.Цитирование примечаний к выпуску сериализации для версии 1.5:

Правила сериализации экземпляра enum отличаются от правил сериализации «обычного» сериализуемого объекта: сериализованная форма экземпляра enumсостоит только из имени константы enum и информации, идентифицирующей его базовый тип enum.Поведение десериализации также отличается - информация о классе используется для поиска соответствующего класса перечисления, и метод Enum.valueOf вызывается с этим классом и полученным именем константы для получения возвращаемой константы перечисления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...