2011-02-07 39 views
28

Tại sao java.util.List không triển khai Serializable trong khi các lớp con như LinkedList, Arraylist làm gì? Nó không có vẻ chống lại các nguyên tắc thừa kế? Ví dụ, nếu chúng tôi muốn gửi một LinkedList qua mạng, chúng tôi phải viết:Tại sao java.util.List không thể thực hiện Serializable?

new ObjectOutputStream(some inputStream).writeObject(some LinkedList); 

Cho đến nay rất tốt, nhưng khi đọc các đối tượng ở phía bên kia chúng ta phải explicity nói LinkedList l = (LinkedList)objectInputStream.readObject(); thay vì List l = (List)objectInputStream.readObject();. Nếu chúng tôi đã từng thay đổi chức năng viết từ LinkedList để nói ArrayList, chúng tôi cũng sẽ phải thay đổi phần đọc. Có List triển khai Serializable sẽ giải quyết được sự cố.

+2

Tôi không nghĩ rằng phần thứ hai của tuyên bố của bạn là chính xác, không phải là tôi đã có cơ hội để thử nó. Bạn nhận được loại lỗi nào? –

Trả lời

35

List không triển khai Serializable vì đó không phải là yêu cầu quan trọng cho danh sách. Không có sự bảo đảm (hoặc cần) rằng mọi sự thực hiện có thể có của một List có thể được tuần tự hóa.

LinkedListArrayList chọn làm như vậy, nhưng điều đó cụ thể cho việc triển khai của chúng. Các triển khai khác List có thể không phải là Serializable.

+2

Trong trường hợp đó cùng một đối số có thể được áp dụng cho LinkedList cũng như là một danh sách rất cơ bản, nó không thể được tuần tự hóa vì nó không phải là một yêu cầu của một danh sách. –

+10

Có sự khác biệt trong việc buộc tất cả việc triển khai danh sách phải được tuần tự hóa và chọn một triển khai cụ thể có thể tuần tự hóa. –

+1

LinkedList là một triển khai, mà các nhà phát triển chọn để cung cấp cho các tài sản serializable. Nếu chúng tôi làm theo lý do của bạn không có lớp học nên thực hiện hai giao diện tại một thời điểm ... – Dunaril

3

List cũng được mở bởi lớp con cụ thể của người dùng, và người triển khai có thể không nhất thiết muốn triển khai Serializable. Khả năng nối tiếp cũng không thuộc về các trách nhiệm chính của một số List, vì vậy không có lý do gì để liên kết cả hai với nhau.

7

Danh sách là một giao diện và làm cho nó mở rộng Serializable có nghĩa là bất kỳ việc triển khai Danh sách nào đều có thể được tuần tự hóa.

Thuộc tính có thể tuần tự không phải là một phần của trừu tượng Danh sách và do đó không cần thiết cho việc triển khai.

1

Hãy xem xét giả thuyết ThreadList implements List<Thread>, chứa danh sách các chuỗi đang hoạt động tại bất kỳ thời điểm nào đã cho. Việc triển khai duyệt qua các chuỗi hoạt động một cách minh bạch và cho phép dễ dàng truy cập vào các chuỗi đó - để thuận tiện cho bạn. Việc triển khai đó có thể được tuần tự hóa hay không (quên rằng Thread không thể tuần tự hóa được)?

Tùy vào người thực hiện giao diện để quyết định xem việc triển khai của cô ấy có an toàn để được tuần tự hóa hay không. List là quá chung chung, như về cơ bản nêu rõ * bộ sưu tập theo thứ tự các mục thuộc loại T`.

3

No. A LinkedList luôn là Danh sách. Khi bạn deserialize danh sách liên kết, kể từ khi một LinkedList là một danh sách, bạn có thể viết

List l = (List) objectInputStream.readObject(); 

Thực tế là l là một LinkedList là không quan trọng. Bạn muốn có một danh sách, và bạn có một danh sách.

+0

Bạn có chắc chắn? Thời gian chạy sẽ hiểu làm thế nào để deserialize đối tượng nếu bạn cast nó vào một giao diện không serializable? – Dunaril

+1

Các diễn viên xảy ra sau khi deserialization và do đó không quan trọng ở đây -> cast vào Danh sách là tốt – Puce

+3

Thời gian chạy biết làm thế nào để seserialize đối tượng vì dòng byte serialized của nó chứa tên của lớp của đối tượng đã được đăng. ObjectInputStream do đó tạo ra một cá thể của lớp này và điền nó với dữ liệu tìm thấy trong đối tượng được tuần tự hóa, và sau đó trả về nó cho người gọi. Người gọi biết rằng đó là danh sách được sắp xếp theo thứ tự, và do đó đưa đối tượng được trả về vào Danh sách. –

-2

Danh sách mở rộng Bộ sưu tập, và nó không thể thực hiện bất cứ điều gì vì nó là một giao diện ...

+3

có lẽ là OP có nghĩa là 'List' sẽ mở rộng' Serializable' * ngoài * vào 'Bộ sưu tập', thực tế là anh ta sử dụng từ thực hiện nên được hiểu trong ngữ cảnh ... – davin

0

Nếu Danh sách thực hiện/mở rộng Serializable thì bạn đã ngụ ý hợp đồng rằng tất cả các lớp học thực hiện/lớp con của Danh sách cũng là Serializable mà không phải lúc nào cũng đúng. Ví dụ: xem triển khai tập hợp ổi của ForwardingListMultimap. Nó không cần phải được Serializable chức năng và điều này đã có thể chỉ vì List không phải là Serializable.

0

Tại sao nó rằng java.util.List không thực hiện Serializable ...

Bởi vì không phải mọi List thực hiện trên thế giới phải Serializable.

trong khi đọc các đối tượng ở phía bên kia chúng ta phải explicity nói ... thay vì

List l = (List) objectInputStream.readObject(); 

Bạn đã thử chưa? Nếu bạn làm thế, tôi nghĩ bạn sẽ thấy nó hoạt động.

1

Câu hỏi của bạn dường như dựa trên sự hiểu lầm. Để sắp xếp một đối tượng, đối tượng (hoặc lớp của nó) phải triển khai Serializable, nhưng bạn không cần sử dụng một biểu thức kiểu Serializable (hoặc một số loại phụ) để thực hiện việc này. Nó là khá cố ý rằng phương pháp writeObject có một kiểu tham số Object và không Serializable, cũng như loại trả về readObject().

Nhưng ngay cả khi những thông số và kiểu trả về được Serializable, bạn sẽ không cần phải biết các loại thực hiện cụ thể:

ObjectOutputStream stream = ...; 
List myList = ...; 
stream.writeObject((Serializable)myList); 

ObjectInputStream stream = ...; 
List myList = (List) stream.readObject(); 

sẽ làm việc cũng như nó hoạt động bây giờ (mà không có diễn xuất có thể nối tiếp).

ObjectInputStream và ObjectOutputStream không quan tâm đến tất cả các loại của bạn khi gọi, chúng chỉ đơn giản là nhìn vào đối tượng trong tầm tay và lớp của nó.

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