Как обеспечить согласованность перечислений в сериализации Java?

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

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

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

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

Ответы

Ответ 1

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

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

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

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

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

Ответ 2

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

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