2013-07-23 12 views
11

Trong Java, các giao diện Bộ sưu tập không mở rộng Nối tiếp được vì một số lý do chính đáng. Ngoài ra, việc triển khai phổ biến nhất của các giao diện này thực hiện Serializable. Vì vậy, các đối tượng thực hiện một trong các giao diện Bộ sưu tập có thể tuần tự hóa nếu thực hiện chính nó có thể tuần tự hóa (thường là trường hợp) nếu các đối tượng trong bộ sưu tập đều có thể tuần tự hóa được.Java: cách đảm bảo các bộ sưu tập có thể tuần tự

Nhưng làm cách nào để đảm bảo rằng hai điều kiện này được đáp ứng? Tôi không muốn chạy vào một lỗi thời gian chạy vì trình biên dịch có thể kiểm tra các điều kiện này. Tôi đang suy nghĩ về một số giao diện rõ ràng như (showcase cho Danh sách giao diện):

public interface SerializableList<T extends Serializable> extends Serializable, List<T> {} 

Tôi tự hỏi nếu không có ai khác đang đối mặt với vấn đề này và đã đưa ra giải pháp dễ dàng này. Cho đến bây giờ tôi đã không thể tìm thấy bất kỳ giải pháp hoặc thậm chí thảo luận về điều này, mà làm cho tôi nghi ngờ về ý tưởng của tôi.

+0

Bạn có thể đặt tham chiếu 'List' thành' 'List ', nếu tôi hiểu chính xác câu hỏi của bạn. Bạn không cần phải tung ra giao diện của riêng bạn. –

+0

Trình biên dịch không thể kiểm tra điều đó. Mỗi lớp thực hiện Serializable có thể chứa một trường không chuyển tiếp, không thể tuần tự hóa, điều này sẽ dẫn đến một ngoại lệ thời gian chạy. Và một ArrayList có thể được serializable nếu các đối tượng thực tế nó chứa được serializable. Nếu điều đó thực sự quan trọng, hãy sử dụng các bài kiểm tra đơn vị. –

+1

@RohitJain: Đề xuất của bạn chỉ đảm bảo rằng các đối tượng trong danh sách có thể được tuần tự hóa, nhưng không phải là chính việc thực hiện Danh sách. – MrD

Trả lời

6

gì bạn về cơ bản yêu cầu là một định nghĩa kiểu tham gia hai loại:

<type-def> a = null;

gì bạn cần là một sự thay thế của <type-def> với một đặc điểm kỹ thuật, đảm bảo rằng các đối tượng được tham chiếu bởi a thực hiện cả hai Serializable như cũng như Collection<? extends Serializable>. Định nghĩa kiểu như vậy không được ngôn ngữ Java hỗ trợ.

Như bạn đã viết, giải pháp rõ ràng nhất có thể tuyên bố giao diện của riêng bạn, tham gia hai giao diện khác:

interface SerializableCollection<T extends Serializable> extends Collection<T>, Serializable {}

vẻ ok, cho đến khi bạn thử một cái gì đó như thế này:

SerializableCollection<String> a = new ArrayList<String>();

Điều này sẽ không biên dịch. Ngay cả khi ArrayList<String> triển khai cả hai Collection<? extends Serializable>Serializable, lớp học không thực hiện SerializableCollection<String>.

Bây giờ, bạn có thể nếu bạn muốn, phá vỡ thậm chí vấn đề này bằng cách tuyên bố một lớp mới:

SerializableArrayList<T extends Serializable> extends ArrayList<T> implements SerializableCollection<T> {}

Bây giờ bạn đã cơ bản kết hợp tất cả mọi thứ bạn cần và sẽ có thể đáp ứng yêu cầu ban đầu:

SerializableCollection<String> a = new SerializableArrayList<String>();

Có đáng để thử không? Trong trường hợp của bạn, bạn phải quyết định, nhưng tôi sẽ nói không.Đối số của tôi là vì điểm đánh dấu Serializable chỉ là một 'nhãn' không chính thức, đảm bảo rằng cả bộ sưu tập của bạn và nội dung của nó đều được thực hiện Serializable vẫn không đảm bảo rằng bộ sưu tập và nội dung của nó thực sự là có thể được đăng.

+1

Cảm ơn bạn. Tôi nghĩ mọi thứ đã rõ ràng đối với tôi. Như bạn và JB Nizet đã nói, tôi không thể tin rằng các đối tượng đang thực hiện giao diện 'Serializable' thực sự có thể tuần tự hóa được (thật đáng tiếc). Tôi nghĩ đây là vấn đề: liệu nó có đáng để nỗ lực không? Tôi sẽ nghĩ về nó nếu nó được áp dụng trong trường hợp của tôi. – MrD

6

Serializable không phải là giao diện tuyệt vời. Nó phải là một chú thích, nếu chúng có sẵn khi nó được triển khai.

Bạn sẽ xử lý số List của số List của thứ gì đó không phải Serializable. Bạn sẽ cần phải đảm bảo không có đối tượng nào không thể tuần tự hóa quá mức xuống đồ thị đối tượng. Không phải tất cả các đối tượng thực hiện Serializable thực sự có thể được tuần tự hóa.

+0

Vì vậy, không có cách nào để thực hiện một kiểm tra thời gian biên dịch cho điều đó? –

+0

'giao diện SerializableCollection > {} 'có thể một cái gì đó như thế này được thực hiện? –

+1

Một 'List' của các đối tượng không phải là' Serializable' không thể được thêm vào 'SerializableList' vì' List' này không thực thi 'Serializable'. Tất nhiên, tôi có thể thêm một 'ArrayList' (có thể tuần tự hóa) có chứa một số đối tượng không được tuần tự hóa - nhưng chỉ khi tôi sử dụng nó làm kiểu thô. Nếu nó được parametrized, trình biên dịch nên phàn nàn về điều này. – MrD

0

Một cách tiếp cận để nhân bản một bộ sưu tập và chứa các đối tượng là

import org.apache.commons.lang3.SerializationUtils; 
... 
ClonedArrayList = SerializationUtils.deserialize(SerializationUtils.serialize(OriginalArrayList)) 

(ví dụ qua sử dụng ArrayList < Loại > (bộ sưu tập) vì SerializationUtils cần giao diện Serializable)

Kính trọng, Gunnar