Обработка десериализации значений enum, которые больше не существуют - PullRequest
3 голосов
/ 05 января 2012

У меня есть перечисление JJJ, которое имеет 3 значения: A, B и C. В предыдущих версиях моей программы у него было одно дополнительное значение: D. Я хотел бы иметь возможность читать в сериализованных объектах, созданных предыдущимиверсии программы, но возникает исключение, когда в сериализованном объекте встречается переменная типа JJJ со значением 'D'.Оптимально, я хотел бы быть в состоянии перехватить процесс десериализации и сказать ему просто сопоставлять буквы D с буквами C., когда он встречает их.

Согласно http://docs.oracle.com/javase/6/docs/platform/serialization/spec/serial-arch.html (сериализация констант Enum), этоне похоже, что есть простой способ сделать это ... Я знаю, что один из подходов - переопределить readObject для классов, которые содержат переменные-члены типа JJJ, но это будет сложно и болезненно из-за размера и области действия.программы (десятки сериализуемых классов имеют переменные-члены типа JJJ и переопределение readObject для обработки поля JJJ означает, что мне придется вручную обрабатывать и все другие поля).

Я также пыталсячтобы решить эту проблему, применив мой собственный подкласс ObjectInputStream, но, к сожалению, биты десериализации enum, которые мне действительно нужно получить и переопределить, чтобы решить эту проблему, являются частными или частными ...

Есть предложения?

Ответы [ 2 ]

0 голосов
/ 22 октября 2014

К вашему сведению, для любой другой бедной души, пытающейся разобраться с этим делом, я решил реализовать это решение:

Я создал специальный интерфейс для перечислений, который выглядит так:

public interface SerialCompatEnum {
    public String convertOldValue(String oldValue);
}

Затем я написал класс, который принимает необработанный сериализованный поток байтов объекта Java в качестве входных данных, обрабатывает его и записывает модифицированную версию потока байтов в произвольный выходной поток.Логика обработки выбирает любые экземпляры перечисления в сериализованном потоке байтов и использует метод convertOldValue для замены константы перечисления в потоке обновленной строкой, которая фактически существует в текущей базе кода.Сначала мы запускаем все наши сериализованные объекты через этот процессор, чтобы предотвратить полные сбои, вызванные отсутствующими константами перечисления.

К сожалению, это не очень чистое или простое решение.: /

0 голосов
/ 05 января 2012

Я на самом деле не пробовал это, но, возможно, это могло бы сработать:

  1. Создать новый класс "oldClass" с точно такими же полями, что и старый.

  2. Расширьте ObjectInputStream так, как этот пост описывает , так что вы десериализуете в экземпляре "oldClass".

  3. В этом "oldClass"вы создали, реализуйте readResolve ()", чтобы вы возвращали экземпляр новой версии вашего класса, изменяя пропущенные поля по своему усмотрению.

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