Если я изменю базовый класс, который расширяет класс Java Exception, мне нужно обновить значение serialVersionUID? - PullRequest
3 голосов
/ 14 сентября 2009

Рассмотрим следующие классы исключений Java:

public class BarException extends RuntimeException {
    // [...]
}

public class FooException extends BarException {
    private static final long serialVersionUID = -5322002268075295537L;

    // [...]
}

Если я хочу обновить иерархию наследования для удаления BarException, чтобы FooException происходило непосредственно из RuntimeException, требуется ли для этого изменение значения serialVersionUID?

// FooException with updated inheritance hierarchy
public class FooException extends RuntimeException {
    private static final long serialVersionUID = ???;

    // [...]
}

Ответы [ 4 ]

5 голосов
/ 14 сентября 2009

Да. «Перемещение классов вверх или вниз по иерархии» приведет к несовместимости с предыдущими сериализованными экземплярами согласно спецификации сериализации .

2 голосов
/ 15 октября 2009

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

Используя примеры из приведенного выше вопроса: FooException происходит от BarException из RuntimeException, а затем удаляется BarException из цепочки наследования, я собрал пример приложения для проверки сериализации и десериализации. в различных комбинациях.

Я получаю следующие результаты:

Пока я сохраняю serialVersionUID без изменений, я могу успешно сериализовать и десериализовать исходный FooException как обновленные FooException, и и наоборот.

Применяются следующие предостережения:

  • Я использую JDK 1.5.0_07 и не пробовал это делать ни в одной другой версии.
  • FooException имеет члены типа int и Exception, которые успешно десериализованы.
  • BarException не добавляет дополнительных членов к RuntimeException.
2 голосов
/ 14 сентября 2009

Спецификация Java 1.5 предполагает, что удаление классов из иерархии наследования является совместимым изменением, поэтому изменение на serialVersionUID не требуется.

Любая дополнительная информация в потоке сериализации, относящаяся к BarException, будет игнорироваться при десериализации в новый FooException (который получен непосредственно из RuntimeException).

0 голосов
/ 15 сентября 2009

Технически, да, но это зависит от того, сохранит ли ваша система сериализованные объекты и от того, как вы управляете развертыванием нового, реорганизованного кода.

Если вы не выполняете постоянство и обновите все развертывание новой версией кода, я не вижу необходимости менять serialVersionUID.

...