какво причинява проблеми с десериализацията?
Бих искал да ви дам малко предистория, преди да отговоря на въпроса ви,
Средата за изпълнение на сериализацията асоциира с всеки сериализиран клас номер на версията, наречен serialVersionUID, който се използва по време на десериализацията, за да се провери дали подателят и получателят на сериализиран обект имат заредени класове за този обект, които са съвместими по отношение на сериализацията. Ако получателят е заредил клас за обекта, който има различен serialVersionUID от този на съответния клас на подателя, тогава десериализацията ще доведе до InvalidClassException.
Ако сериализиращ се клас не декларира изрично serialVersionUID, тогава времето за изпълнение на сериализацията ще изчисли стойността на serialVersionUID по подразбиране за този клас въз основа на различни аспекти на класа. Той използва следната информация за класа, за да изчисли SerialVersionUID,
- Името на класа.
- Модификаторите на класа, записани като 32-битово цяло число.
- Името на всеки интерфейс, сортиран по име.
- За всяко поле от класа, сортирано по име на полето (с изключение на частни статични и частни преходни полета:
- Името на полето.
- Модификаторите на полето, записани като 32-битово цяло число.
- Описателят на полето.
-
ако съществува инициализатор на клас, напишете следното:
Името на метода, .
Модификаторът на метода, java.lang.reflect.Modifier.STATIC, написан като 32-битово цяло число.
Дескрипторът на метода, ()V.
-
За всеки нечастен конструктор, сортиран по име на метод и подпис:
Името на метода, .
Модификаторите на метода, записани като 32-битово цяло число.
Дескрипторът на метода.
-
За всеки нечастен метод, сортиран по име и подпис на метода:
Името на метода.
Модификаторите на метода, записани като 32-битово цяло число.
Дескрипторът на метода.
И така, за да отговоря на въпроса ви,
Би ли проблем премахването на публична/частна собственост? Добавяне на нови имоти, може би? Ще създаде ли проблеми добавянето на нова функция към класа? Какво ще кажете за повече конструктори?
Да, всички тези добавяния/премахвания по подразбиране ще причинят проблема.
Но един от начините да се преодолее това е да се дефинира изрично SerialVersionUID, това ще каже на системата за сериализация, че знам, че класът ще се развива (или еволюира) с течение на времето и няма да хвърля грешка. Така че системата за десериализация чете само онези полета, които присъстват и от двете страни, и присвоява стойността. Новодобавените полета от страната на десериализацията ще получат стойностите по подразбиране. Ако някои полета бъдат изтрити от страна на десериализацията, алгоритъмът просто чете и прескача.
Следва начинът, по който може да се декларира SerialVersionUID,
private static final long serialVersionUID = 3487495895819393L;