2012-02-04 36 views
27

Nếu tôi có B mở rộng A ... và A thực hiện Serializable, tôi có phải viết "B thực hiện Serializable"?Nếu lớp của tôi triển khai Serializable, tôi có phải triển khai nó trong các lớp con của nó không?

Tôi nghĩ rằng không có, nhưng tôi muốn xác nhận ...

cũng nếu tôi đặt id serialization trong A ... tôi cần phải đặt một trong B cũng? nên serialization id trong A được bảo vệ (không riêng tư)?

+2

Không được âm thanh quái gở, nhưng nó sẽ mất ít thời gian để chỉ cố gắng này hơn nó mất bạn viết câu hỏi này. –

+0

Không phải là âm thanh lén lút, nhưng đây sẽ là một trang web rất, rất nhỏ nếu lời khuyên đó được chú ý nhất quán. –

Trả lời

15

Có. subclass không cần đánh dấu serializable một cách rõ ràng.

và, đánh dấu id là protected sẽ thực hiện. (Từ góc độ biên dịch)

Nhưng, như thực hành tốt mỗi lớp nên có nó riêng serialVersionUid

+0

cảm ơn, bất kỳ ý tưởng làm thế nào để thoát khỏi cảnh báo nhật thực màu vàng về không có id phiên bản nối tiếp tuyên bố? – ycomp

+0

Cách mạnh mẽ hơn sẽ được xác định là 'kết quả tĩnh riêng tư ' – Azodious

+3

có. từ tài liệu "Tất cả các kiểu con của một lớp tuần tự có thể tự tuần tự hóa được." http://download.java.net/jdk8/docs/api/java/io/Serializable.html – vsingh

3

Không, bởi vì B đã thực hiện nó thông qua lớp cơ sở A. Đó là những gì thừa kế là tất cả về.

8

Đánh dấu id như bảo vệ sẽ đủ từ góc độ biên dịch. Tuy nhiên, về mặt lý thuyết, điểm của trường serialVersionUID trên lớp Serializable là dễ dàng phân biệt "phiên bản" của lớp khi deserializing nó - để biểu thị rõ ràng khi một đối tượng nhất định có thể được deserialized vào một thể hiện của lớp được cung cấp (nếu serialVersionUID s là khác nhau, ngoại lệ được ném). Nếu bạn muốn có thể theo dõi rõ ràng các phiên bản và bản chất của một đối tượng, hãy khai báo serialVersionUID trên mỗi lớp con.

+0

Tôi nghĩ rằng 'serialVersionUIDs' được khai báo cho JVM để xác định sự thay đổi trong lớp. và JVM có thể lấy nó từ lớp cơ sở để nó không tạo nên sự khác biệt nào. – Azodious

+0

Vâng vâng, nhưng quan điểm của tôi thực sự là, không đối xử với serialVersionUID như là một khó chịu bạn đang cố gắng để thoát khỏi. Tìm hiểu lý do tại sao nó ở đó và xử lý nó một cách thích hợp. –

+0

Có, nhưng chúng tôi có thể có hai lớp khác nhau với cùng một 'serialVersionUID'. nếu đó là một lớp đơn giản mà không mở rộng bất kỳ lớp nào một cách rõ ràng, thì nó sẽ là bắt buộc. – Azodious

7

Trong thỏa thuận của tôi với câu trả lời @azodious, lớp con kế thừa các thuộc tính có thể tuần tự của lớp cha, nhưng bạn sẽ phải khai báo serialVersionUID một cách rõ ràng.

Từ tài liệu Java: https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html

Nó cũng được mạnh mẽ khuyến cáo rằng serialVersionUID rõ ràng tờ khai sử dụng modifier tin nếu có thể, kể từ tuyên bố đó chỉ áp dụng cho lớp ngay lập tức tuyên bố - lĩnh vực serialVersionUID là không hữu ích như các thành viên được thừa kế.

8

Bạn không phải đánh dấu rõ ràng nguồn gốc là Serializable, nó sẽ được kế thừa. Tuy nhiên, serialVersionUID từ cha mẹ, mặc dù được kế thừa, sẽ không được sử dụng bởi quá trình tuần tự hóa. Nếu bạn không thêm một serialVersionUID vào một con sẽ được tạo ra.

Xem Dưới đây:

public class A implements Serializable { 
    protected static final long serialVersionUID = 1L; 
} 

public class B extends A { 
} 

public class Main { 

    public static void main(String[] args){ 

     A a = new A(); 
     B b = new B(); 

     Class aClass = a.getClass(); 
     Class bClass = b.getClass(); 

     long aUid = ObjectStreamClass.lookup(aClass).getSerialVersionUID(); 
     long bUid = ObjectStreamClass.lookup(bClass).getSerialVersionUID(); 

     System.out.printf("serialVersionUID:\n"); 
     System.out.printf("b inherited from a: %d\n", b.serialVersionUID); 
     System.out.printf("a used by serialization: %d\n",aUid); 
     System.out.printf("b used by serialization: %d\n",bUid); 
    } 

} 

Output:

serialVersionUID:

b kế thừa từ một: 1

một được sử dụng bởi serialization: 1

b sử dụng theo tuần tự hóa: -367523 2183873847366

3

Một đối tượng Java có thể tuần tự hóa nếu lớp của nó hoặc bất kỳ siêu lớp nào thực hiện java.io.Giao diện serializable hoặc subinterface của nó, java.io.Externalizable.

Bạn có thể có một cái nhìn tại tài liệu chính thức và tìm thấy điều này có: https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html

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