2012-08-09 44 views
5

tôi có chữ ký lớp sau và ClientEventSourc thực hiện Serializable:Hiểu biết về FindBugs cảnh báo về lĩnh vực serialVersionUID

public class Grid extends ClientEventSource implements Focusable, FramingBlockWrapper,LIMSEditableField 

Bây giờ FindBugs được niêm yết này là tinh ranh:

Class là Serializable, nhưng không xác định serialVersionUID

Lớp này triển khai Serializable nhưng không xác định trường serialVersionUID. Một thay đổi đơn giản như việc thêm tham chiếu đến đối tượng .class sẽ thêm trường tổng hợp vào lớp, sẽ không may thay đổi hàm serialVersionUID ngầm định (ví dụ: thêm tham chiếu vào String.class sẽ tạo trường tĩnh class $ java $ lang $ String). Ngoài ra, mã nguồn khác nhau để bytecode trình biên dịch có thể sử dụng quy ước đặt tên khác nhau cho các biến tổng hợp được tạo ra để tham chiếu đến các đối tượng lớp hoặc các lớp bên trong. Để đảm bảo khả năng tương tác của Serializable trên các phiên bản, hãy cân nhắc thêm serialVersionUID rõ ràng.

Một số người có thể giải thích ý nghĩa của nó và cách tốt nhất có thể để khắc phục điều này là gì?

Trả lời

7

serialVersionUID được sử dụng để deserialize lớp học của bạn. nó được tạo tự động theo mặc định.
nhưng thay đổi bất kỳ thứ gì trong lớp học của bạn sẽ tạo ra một serialVersionUID khác và bạn không thể deserialise các đối tượng "cũ".
để bạn xác định serialVersionUID của riêng mình để giúp deserialisation tìm đúng lớp.

thêm một biến như thế này để mã của bạn:

private static final long serialVersionUID = 6106269076155338045L; 

để tham khảo vào việc tạo ra UID của bạn:

Does it matter what I choose for serialVersionUID when extending Serializable classes in Java?

+0

có bất kỳ thuật toán/chương trình nào tạo số này không? Tôi có nghĩa là nó có thể là bất cứ điều gì hoặc nó cần phải làm theo một số thực hành tốt nhất như hashcode() làm như descibed trong sách java hiệu quả và thực hiện trong EqualsBuilder và HashCodeBuilder từ commache apache. – Geek

+0

Con số này có thể là bất cứ điều gì, miễn là nó là duy nhất trong số các lớp được sắp xếp theo thứ tự của bạn. Eclipse f.e. có máy phát điện riêng, nhưng bạn có thể sử dụng bất kỳ số nào. – Kostronor

2

một số có thể giải thích ý nghĩa của nó

Thay đổi nhỏ đối với lớp học thay đổi số serialVersionUID mà bạn không muốn vì điều này có thể ngăn chặn quá trình deserialization không có lý do chính đáng.

và cách tốt nhất để khắc phục điều này là gì?

Đặt như nó gợi ý.

private static final long serialVersionUID = 1; 

có bất kỳ thuật toán/chương trình mà tạo ra con số này

Yes. Đây là thuật toán bạn đang cố bỏ qua, chứ không phải tạo lại. Chỉ cần bắt đầu tại 1.

Tôi có nghĩa là nó có thể được bất cứ điều gì hoặc nó cần phải làm theo một số thông lệ tốt nhất

tôi sẽ đề nghị sử dụng 1 là thực hành tốt nhất bởi vì nó làm cho nó rõ ràng đây là một giá trị overriden tùy tiện chọn. Sử dụng một giá trị lớn như 6106269076155338045L có thể trông giống như một số được tạo hoặc chọn số lý do này.

+0

Đây có phải là lựa chọn tốt không? Bạn có thể trả lời bình luận của tôi cho câu trả lời của Kostronor không. – Geek

+0

Việc lựa chọn giá trị không quan trọng. Bạn nên thay đổi nó bất cứ khi nào bạn thực hiện một thay đổi phá vỡ. tức là bất cứ khi nào bạn thực hiện một thay đổi mà bạn không muốn các phiên bản khác để deserialize như phiên bản này. Theo kinh nghiệm của tôi, điều này gần như không bao giờ. ;) –

1

Giá trị này được sử dụng tại quá trình deserialization. Mục đích của nó là duy trì tính tương thích giữa các lớp và các đối tượng tuần tự tương ứng của chúng. Nếu bạn tuần tự hóa một đối tượng kiểu A và sau đó thay đổi A bằng cách nào đó, thì cơ chế này ngăn không cho bạn deserializing đối tượng; đối tượng và lớp của nó sẽ không khớp và bạn sẽ gặp phải lỗi thời gian chạy.

Có một số serialver.exe trong JDK. Nếu bạn cho nó một tập tin .class làm tham số, nó sẽ nhổ ra một serialVersionUID. Hầu hết các IDE đã chức năng này được xây dựng trong

Ví dụ về đầu vào:.

> serialver MyClass 

(có đã tồn tại một tập tin MyClass.classMyClass phải thực hiện Serializable)

Ví dụ về đầu ra:

> MyClass: static final long serialVersionUID = -8174364448753809256L; 

Nếu bạn ghét làm mọi thứ ở dòng lệnh, hãy thực hiện chương trình như sau:

> serialver -show 

sẽ hiển thị giao diện này:

serialver screenshot

Sau đó bạn có thể gõ tên của lớp và bấm vào nút "Xem".

Tôi khuyên bạn nên đọc về quy trình tuần tự hóa nếu bạn quan tâm. Bạn sẽ tìm hiểu chính xác lý do tại sao ID phiên bản này là cần thiết, các trường/phương thức nào được tính đến khi tạo và nhiều hơn nữa.

+0

bạn biết cách thực hiện điều này trong Intellij Idea? – Geek

+0

@Geek Không, xin lỗi. Tôi chỉ sử dụng IDE đó trong một vài giờ ... Tôi biết cách làm điều đó trong Eclipse và trong Netbeans. –

Các vấn đề liên quan