2012-02-23 36 views
6

Tôi phải sắp xếp một đối tượng phức tạp, nhưng một thành phần của nó không được tuần tự hóa (đối tượng đồ thị của bên thứ ba), vì vậy tôi đã tạo một phiên bản tùy chỉnh có thể tuần tự hóa của lớp Graph này và đã sử dụng Danh sách biến đổi danh sách để chuyển đổi đối tượng không thể tuần tự hóa thành các đối tượng tùy chỉnh. Các writeObject serialization vẫn không thành công. Tôi sẽ quan tâm để biết tại sao? Giả định của tôi là Lists.transform thực hiện hoạt động của nó Lazily (Giữ một tham chiếu ẩn cho đối tượng ban đầu.)Vấn đề serialization Java, trong khi sử dụng ổi Lists.transform

Ngoài ra còn có một giải pháp cho vấn đề này?

Trả lời

11

Lists.transform() không hoạt động như bạn nghi ngờ. Bạn có thể làm một trong

Lists.newArrayList(Lists.transform(...)) 

hoặc, nếu bạn muốn có một phiên bản bất biến,

ImmutableList.copyOf(Lists.transform(...)) 

và sau đó serialize danh sách kết quả.

+0

Bạn không có để tạo danh sách mới, hãy xem câu trả lời @eneveu. – Xaerxess

+2

OP cho biết rằng fromList đặc biệt đầy đủ các phần tử không thể tuần tự hóa. –

+1

@Xin bạn có thể sửa đổi nhận xét của mình không? Bạn không thể nhận được một danh sách serializable chỉ bằng cách sử dụng lừa enum (@eneveu trả lời). Câu trả lời này là hữu ích nhất liên quan đến câu hỏi. –

1

Nếu bạn cố gắng sắp xếp lại một danh sách được trả về từ danh sách # transform, bản thân danh sách giao diện là không Serializable.

+1

Tại sao đó lại là một vấn đề? Đó là việc thực hiện được xem xét trong quá trình tuần tự hóa. Và việc thực hiện trả về bởi Lists.transform() thực hiện Serializable: "Danh sách trả về luôn thực hiện Serializable, nhưng serialization sẽ thành công chỉ khi fromList và chức năng được serializable." (từ [javadoc] (http://docs.guava-libraries.googlecode.com/git-history/v11.0.1/javadoc/com/google/common/collect/Lists.html)) –

6

Lists.transform() trả về chế độ xem được chuyển đổi của danh sách gốc. Từ Lists.transform() javadoc:

Danh sách quay trở lại luôn luôn thực hiện Serializable, nhưng serialization sẽ chỉ thành công khi fromList và chức năng là serializable.

Khi tuần tự hóa chế độ xem đã chuyển đổi, bạn thực sự đang sắp xếp danh sách gốc cùng với hàm. Trong trường hợp của bạn, nó không thành công vì danh sách gốc của bạn không được tuần tự hóa (vì nó chứa các phần tử đồ thị không tuần tự hóa). Nhưng nó cũng có thể thất bại vì chức năng không thực hiện tuần tự.

BTW, có một mẹo nhỏ để tạo các hàm có thể tuần tự mà không có độ dài. Thay vì thực hiện:

private static final class MyFunction extends Function<String, String> implements Serializable { 
    private static final MyFunction INSTANCE = new MyFunction(); 

    @Override 
    public String apply(String input) { 
     return "[" + input + "]"; 
    } 

    private Object readResolve() { 
     return INSTANCE; 
    } 
    private static final long serialVersionUID = 1; 
    } 

Bạn có thể sử dụng mô hình enum singleton, đó là rất nhiều ít tiết, và được bạn serialization cho miễn phí (vì enums là serializable). Nó cũng đảm bảo rằng Chức năng của bạn là một singleton:

// enum singleton pattern 
    private enum MyFunction implements Function<String, String> { 
    INSTANCE; 

    @Override 
    public String apply(String input) { 
     return "[" + input + "]"; 
    } 
    } 
+2

Tuyệt vời ... Hiệu quả Java. Cảm ơn bạn. –

+1

Vâng, Joshua Bloch giải thích trong Java hiệu quả rằng đó là cách tốt nhất để tạo ra một singleton. Một enum là serializable, nó không dễ bị tấn công de-serialization khác nhau, và JVM đảm bảo tính duy nhất của nó. Bạn có thể tìm thấy các ví dụ hay về mẫu trong thư viện ổi: http://code.google.com/p/guava-library/source/browse/guava/src/com/google/common/base/Functions.java # 59 –

+0

Điểm thưởng để trích dẫn EJ và cho các ứng dụng có mẫu tốt trong ổi, ngay cả khi câu trả lời là không ' t hữu ích vì 'fromList' sẽ không được serializable. –

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