serialVersionUID
ułatwia wersjonowanie zserializowanych danych. Jego wartość jest przechowywana z danymi podczas serializacji. Podczas usuwania serializacji sprawdzana jest ta sama wersja, aby zobaczyć, jak dane serializowane są zgodne z bieżącym kodem.
Jeśli chcesz zaktualizować swoje dane, zwykle zaczynasz serialVersionUID
od zera i podbijasz je przy każdej zmianie strukturalnej w swojej klasie, która zmienia zserializowane dane (dodawanie lub usuwanie nieprzechodzących pól).
Wbudowany mechanizm deserializacji ( in.defaultReadObject()
) odmówi deserializacji ze starych wersji danych. Ale jeśli chcesz, możesz zdefiniować własną funkcję readObject (), która może odczytywać stare dane. Ten niestandardowy kod może następnie sprawdzić serialVersionUID
, aby dowiedzieć się, w której wersji znajdują się dane, i zdecydować, w jaki sposób należy dokonać serializacji. Ta technika wersjonowania jest przydatna, jeśli przechowujesz serializowane dane, które przetrwają kilka wersji twojego kodu.
Ale przechowywanie danych zserializowanych przez tak długi okres nie jest zbyt powszechne. O wiele bardziej powszechne jest stosowanie mechanizmu serializacji do tymczasowego zapisywania danych na przykład w pamięci podręcznej lub wysyłania ich przez sieć do innego programu z tą samą wersją odpowiednich części bazy kodu.
W takim przypadku nie jesteś zainteresowany zachowaniem kompatybilności wstecznej. Zajmujesz się tylko upewnieniem się, że komunikujące się bazy kodu rzeczywiście mają te same wersje odpowiednich klas. Aby ułatwić taką kontrolę, musisz zachować ją serialVersionUID
tak jak poprzednio i nie zapomnij zaktualizować jej podczas wprowadzania zmian w swoich klasach.
Jeśli zapomnisz zaktualizować pole, możesz skończyć z dwiema różnymi wersjami klasy o innej strukturze, ale o tej samej serialVersionUID
. Jeśli tak się stanie, domyślny mechanizm ( in.defaultReadObject()
) nie wykryje żadnej różnicy i spróbuje usunąć serializację niekompatybilnych danych. Teraz możesz skończyć z tajemniczym błędem środowiska wykonawczego lub cichą awarią (pola zerowe). Tego rodzaju błędy mogą być trudne do znalezienia.
Aby pomóc w tym przypadku, platforma Java oferuje wybór nie ustawiania serialVersionUID
ręcznie. Zamiast tego w czasie kompilacji zostanie wygenerowany skrót struktury klasy i użyty jako identyfikator. Ten mechanizm zagwarantuje, że nigdy nie będziesz mieć różnych struktur klas o tym samym identyfikatorze, a więc nie dostaniesz wspomnianych wyżej trudnych do prześledzenia błędów serializacji.
Ale istnieje strategia automatycznego generowania identyfikatorów. Mianowicie, że wygenerowane identyfikatory dla tej samej klasy mogą się różnić między kompilatorami (jak wspomniano powyżej Jon Skeet). Jeśli więc komunikujesz dane serializowane między kodem skompilowanym za pomocą różnych kompilatorów, zalecane jest ręczne utrzymanie identyfikatorów.
A jeśli jesteś wstecznie zgodny ze swoimi danymi, tak jak w pierwszym wspomnianym przypadku użycia, prawdopodobnie również chcesz sam zachować identyfikator. Ma to na celu uzyskanie czytelnych identyfikatorów i większą kontrolę nad tym, kiedy i jak się zmieniają.