serialVersionUID
tạo điều kiện cho phiên bản của dữ liệu nối tiếp. Giá trị của nó được lưu trữ cùng với dữ liệu khi tuần tự hóa. Khi hủy tuần tự hóa, cùng một phiên bản được kiểm tra để xem cách dữ liệu nối tiếp khớp với mã hiện tại.
Nếu bạn muốn phiên bản dữ liệu của mình, bạn thường bắt đầu bằng serialVersionUID
0 và kết hợp nó với mọi thay đổi cấu trúc đối với lớp của bạn để thay đổi dữ liệu được tuần tự hóa (thêm hoặc xóa các trường không tạm thời).
Cơ chế khử tuần tự hóa tích hợp ( in.defaultReadObject()
) sẽ từ chối khử tuần tự hóa từ các phiên bản cũ của dữ liệu. Nhưng nếu bạn muốn, bạn có thể xác định chức năng readObject () của riêng bạn để có thể đọc lại dữ liệu cũ. Mã tùy chỉnh này sau đó có thể kiểm tra serialVersionUID
để biết dữ liệu nằm trong phiên bản nào và quyết định cách khử tuần tự hóa nó. Kỹ thuật tạo phiên bản này rất hữu ích nếu bạn lưu trữ dữ liệu tuần tự tồn tại một số phiên bản mã của bạn.
Nhưng lưu trữ dữ liệu nối tiếp trong một khoảng thời gian dài như vậy không phải là rất phổ biến. Việc sử dụng cơ chế tuần tự hóa để tạm thời ghi dữ liệu vào bộ đệm hoặc gửi nó qua mạng đến một chương trình khác có cùng phiên bản của các phần có liên quan của cơ sở dữ liệu.
Trong trường hợp này, bạn không quan tâm đến việc duy trì khả năng tương thích ngược. Bạn chỉ quan tâm đến việc đảm bảo rằng các cơ sở mã đang giao tiếp thực sự có cùng phiên bản của các lớp có liên quan. Để tạo điều kiện kiểm tra như vậy, bạn phải duy trì serialVersionUID
giống như trước đây và không quên cập nhật nó khi thay đổi các lớp học của bạn.
Nếu bạn quên cập nhật trường, bạn có thể kết thúc với hai phiên bản khác nhau của một lớp có cấu trúc khác nhau nhưng có cùng cấu trúc serialVersionUID
. Nếu điều này xảy ra, cơ chế mặc định ( in.defaultReadObject()
) sẽ không phát hiện bất kỳ sự khác biệt nào và cố gắng hủy tuần tự hóa dữ liệu không tương thích. Bây giờ bạn có thể kết thúc với một lỗi thời gian chạy khó hiểu hoặc lỗi im lặng (các trường null). Những loại lỗi này có thể khó tìm.
Vì vậy, để giúp usecase này, nền tảng Java cung cấp cho bạn một lựa chọn không cài đặt serialVersionUID
thủ công. Thay vào đó, một hàm băm của cấu trúc lớp sẽ được tạo tại thời gian biên dịch và được sử dụng làm id. Cơ chế này sẽ đảm bảo rằng bạn không bao giờ có các cấu trúc lớp khác nhau với cùng một id và do đó bạn sẽ không gặp phải các lỗi tuần tự hóa thời gian chạy khó theo dõi được đề cập ở trên.
Nhưng có một mặt trái của chiến lược id được tạo tự động. Cụ thể là các id được tạo cho cùng một lớp có thể khác nhau giữa các trình biên dịch (như đã đề cập bởi Jon Skeet ở trên). Vì vậy, nếu bạn giao tiếp dữ liệu tuần tự giữa các mã được biên dịch với các trình biên dịch khác nhau, bạn nên duy trì id theo cách thủ công.
Và nếu bạn tương thích ngược với dữ liệu của bạn như trong trường hợp sử dụng đầu tiên được đề cập, có lẽ bạn cũng muốn tự duy trì id. Điều này để có được id có thể đọc và kiểm soát tốt hơn khi nào và cách chúng thay đổi.