serialVersionUID
полегшує версію серіалізованих даних. Його значення зберігається з даними при серіалізації. Під час десеріалізації та сама версія перевіряється, як серіалізовані дані відповідають поточному коду.
Якщо ви хочете оновлювати свої дані, зазвичай ви починаєте з serialVersionUID
0 і додаєте їх до кожного структурного зміни до свого класу, який змінює серіалізовані дані (додавання або видалення непрохідних полів).
Вбудований механізм десеріалізації ( in.defaultReadObject()
) відмовиться від десерталізації зі старих версій даних. Але якщо ви хочете, ви можете визначити власну функцію readObject (), яка може читати старі дані. Цей спеціальний код може потім перевірити serialVersionUID
вхід, щоб дізнатись, у якій версії є дані, і вирішити, як де-серіалізувати їх. Цей прийом версій корисний, якщо ви зберігаєте серіалізовані дані, які переживають кілька версій вашого коду.
Але зберігання серіалізованих даних протягом такого тривалого періоду часу не дуже поширене. Набагато частіше використовувати механізм серіалізації для тимчасового запису даних, наприклад, в кеш, або надсилання їх по мережі в іншу програму з тією ж версією відповідних частин кодової бази.
У цьому випадку ви не зацікавлені у підтримці зворотної сумісності. Ви стурбовані лише тим, щоб переконатися, що кодові бази, які передаються, дійсно мають однакові версії відповідних класів. Щоб полегшити таку перевірку, ви повинні підтримувати так serialVersionUID
само, як раніше, і не забувати оновлювати її, вносячи зміни до своїх класів.
Якщо ви забудете оновити поле, можливо, ви отримаєте дві різні версії класу з різною структурою, але з однаковою serialVersionUID
. Якщо це трапиться, механізм за замовчуванням ( in.defaultReadObject()
) не виявить різниці і спробує десертизувати несумісні дані. Тепер у вас може виникнути криптична помилка виконання або безшумний збій (нульові поля). Ці типи помилок можуть бути важко знайти.
Отож, щоб допомогти цьому випадку використання, платформа Java пропонує вам вибір не встановлювати serialVersionUID
вручну. Натомість хеш структури класу буде генеруватися під час компіляції та використовуватись як id. Цей механізм гарантує, що ви ніколи не маєте різних структур класу з однаковим ідентифікатором, і тому ви не отримаєте цих важко відстежуваних невдач серіалізації виконання, згаданих вище.
Але є зворотна сторона стратегії автоматичного створення ідентифікатора. А саме, що згенеровані ідентифікатори для одного класу можуть відрізнятися між компіляторами (як згадував Джон Скіт вище). Отже, якщо ви передаєте серіалізовані дані між кодом, зібраним з різними компіляторами, рекомендується підтримувати ідентифікатори вручну в будь-якому випадку.
І якщо ви назад сумісні з вашими даними, як, наприклад, у першому згаданому випадку використання, ви, ймовірно, хочете зберегти ідентифікатор самостійно. Це для того, щоб отримати читабельні ідентифікатори та мати більший контроль над тим, коли та як вони змінюються.