Рассмотрите следующую ситуацию:
Существует файл сериализации, созданный более старой версией приложения. К сожалению, пакет изменился для класса, который был сериализирован. И теперь я должен загрузить информацию из этого файла в тот же класс, но расположенный в другом пакете. Этот класс имеет serialVersionUID
определенный и не изменился (т.е. совместимо).
Вопрос: действительно ли возможно загрузить новые экземпляры класса из этого файла с помощью каких-либо приемов (кроме тривиального копирования класса в старый пакет и затем использование логики обертки десериализации)? Возможно использовать readResolve()
восстановиться с перемещения/переименования класса? В противном случае объясните почему.
Вопрос: Можно ли загрузить экземпляры нового класса из этого файла с помощью каких-либо уловок (кроме тривиальных {{ 1}} копируя класс в старый пакет и затем используя логику десериализации оболочки )?
Я не думаю, что есть какие-то другие "уловки", которые не включают хотя бы частичную повторную реализацию протокола сериализации.
Можно ли использовать readResolve () для восстановления после перемещения / переименования класса ? Если нет, объясните почему.
Нет, потому что механизм десериализации выйдет из строя намного раньше, на этапе, когда он пытается найти класс, который десериализуется - у него нет возможности узнать, что класс в другом пакете имеет readResolve ()
, который предполагается использовать.
Я не думаю, что возможно делать то, что вы хотите.
Формат файла сериализации сохраняет имена классов. Подробно он имеет следующую структуру:
AC ED
номер версии протокола
данные объекта
описание класса объекта
Описание класса имеет следующий формат:
полное имя класса
серийная версия уникальна ID (SHA1 из подписей полей и методов)
параметры сериализации
дескрипторы полей
Когда вы пытаетесь десериализовать объект, механизм сериализации сначала сравнивает имена классов (и вы не проходите этот шаг), затем он сравнивает serialVersionUID и только после прохождения этих двух шагов десериализует объект.
Возможно, лучше всего будет воссоздать старый класс (имя, пакет и серийный ID), прочитать сериализованную форму, затем скопировать данные в экземпляр нового объекта и повторно сериализовать его.
Если у вас много таких сериализованных объектов, возможно, вы можете написать небольшой сценарий для этого, чтобы "изменение схемы" происходило за один раз.
Другой вариант - воскресить старый класс и реализовать его метод readResolve, чтобы вернуть экземпляр нового класса (возможно, объявив конструктор копирования). Лично я думаю, что я бы выбрал сценарий изменения схемы, а затем удалил бы старый класс навсегда.