Co způsobuje problémy s deserializací?
Než odpovím na vaši otázku, rád bych vám poskytl trochu pozadí,
Runtime serializace přidruží ke každé serializovatelné třídě číslo verze nazývané serialVersionUID, které se používá během deserializace k ověření, že odesílatel a příjemce serializovaného objektu načetli třídy pro tento objekt, které jsou kompatibilní s ohledem na serializaci. Pokud příjemce načetl pro objekt třídu, která má jiné serialVersionUID, než má odpovídající třída odesílatele, bude výsledkem deseralizace výjimka InvalidClassException.
Pokud serializovatelná třída explicitně nedeklaruje serialVersionUID, pak serializační runtime vypočítá výchozí hodnotu serialVersionUID pro tuto třídu na základě různých aspektů třídy. K výpočtu SerialVersionUID používá následující informace o třídě,
- Název třídy.
- Modifikátory třídy zapsané jako 32bitové celé číslo.
- Název každého rozhraní seřazený podle názvu.
- Pro každé pole třídy seřazené podle názvu pole (kromě soukromých statických a soukromých přechodných polí:
- Název pole.
- Modifikátory pole zapsané jako 32bitové celé číslo.
- Deskriptor pole.
-
pokud existuje inicializátor třídy, zapište si následující:
Název metody, .
Modifikátor metody, java.lang.reflect.Modifier.STATIC, zapsaný jako 32bitové celé číslo.
Deskriptor metody, ()V.
-
Pro každý nesoukromý konstruktor seřazený podle názvu metody a podpisu:
Název metody, .
Modifikátory metody zapsané jako 32bitové celé číslo.
Deskriptor metody.
-
Pro každou nesoukromou metodu seřazenou podle názvu metody a podpisu:
Název metody.
Modifikátory metody zapsané jako 32bitové celé číslo.
Deskriptor metody.
Takže, abych odpověděl na vaši otázku,
Způsobilo by odstranění veřejného/soukromého majetku problém? Možná přidávání nových vlastností? Způsobilo by přidání nové funkce do třídy problémy? Co takhle více konstruktérů?
Ano, všechna tato přidání/odebrání ve výchozím nastavení způsobí problém.
Ale jeden způsob, jak to překonat, je explicitně definovat SerialVersionUID, což řekne systému serializace, že vím, že se třída bude časem vyvíjet (nebo se vyvine) a nevyvolá chybu. Systém de-serializace tedy čte pouze ta pole, která jsou přítomna na obou stranách, a přiřazuje hodnotu. Nově přidaná pole na straně de-serializace získají výchozí hodnoty. Pokud jsou některá pole odstraněna na straně de-serializace, algoritmus pouze čte a přeskakuje.
Následuje způsob, jak lze deklarovat SerialVersionUID,
private static final long serialVersionUID = 3487495895819393L;