2012-10-11 41 views
14

Java chứa nhiều lớp (như trong Swing), thực hiện dreaded and error proneinterface Serializable.Cách tốt nhất để tạo lớp không thể thực hiện được là gì?

Nếu bạn triển khai, hãy TableModel mới bằng cách mở rộng AbstractTableModel, mô hình mới phải có thể tuần tự hóa được, nhưng nếu nó chứa các kiểu dữ liệu nội bộ không thể tuần tự hóa được và không cần phải kể từ khi bạn không lên kế hoạch để sử dụng tính năng này?

Trong trường hợp này, các công cụ như Sonar phát điên. Một trong hai khiếu nại rằng "Class Foo xác định trường hợp không phải là trường hợp không thể tuần tự hóa bar".

Vì vậy, tôi chắc rằng lĩnh vực transient chỉ để có được "Trường Foo.bar là thoáng qua nhưng không được thiết lập bởi deserialization"

Có thể nói "Không, lớp này là không serializable, và tôi don' Tôi muốn nó là "theo cách mà bạn không nhận được bất kỳ lỗi nào trong các công cụ như Sonar?

+0

Liệu Sonar hỗ trợ ức chế của một cảnh báo cho một lớp học cá nhân? Trong IntelliJ nó cung cấp cho bạn tùy chọn để thêm @SuppressWarning vào lớp cho bạn để kiểm tra này. –

+0

Sonar chỉ chạy FindBugs, PMD và CheckStyle trên mã của bạn và tổng hợp kết quả. Vì vậy, một giải pháp mà giữ những ba yên tĩnh sẽ làm việc cho tôi. '@ SuppressWarning' hoạt động như mong đợi. Ngoài ra còn có các plugin cho phép bỏ qua các cảnh báo bằng những thứ như tên tệp, đường dẫn hoặc mẫu Chuỗi. –

+0

Đó không phải là những gì 'thoáng qua' dành cho? – EJP

Trả lời

20

Trích dẫn từ JavaRevisited article này (xem # 8):

Để tránh java serialization bạn cần phải thực hiện phương pháp writeObject() và readObject() trong lớp của mình và cần phải ném NotSerializableException từ những phương pháp.

Vì vậy, bạn chỉ cần dán vào lớp học của bạn:

private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException { 
    throw new java.io.NotSerializableException(getClass().getName()); 
} 

private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException { 
    throw new java.io.NotSerializableException(getClass().getName()); 
} 
+0

Wow, không biết về 'NotSerializableException' – AlexR

+0

Tôi đã xác minh giải pháp này và nó hoạt động. Sonar, FindBugs và PMD tất cả dường như kiểm tra 'NotSerializableException'. –

+2

Âm thanh lạ: Thực hiện giao diện Serializable và ném một NotSerializableException, trong khi serializing. Cách duy nhất tôi thấy là tạo một Proxy-Class, không thể tuần tự hóa một delegate tất cả các phương thức để thực hiện cụ thể. Nhưng đó là một cái gì đó giống như nuking một con chim nhỏ bé. –

0

tôi có thể suy nghĩ về phương pháp thực hiện private void writeObject() như sau:

private void writeObject(ObjectOutputStream oos) throws IOException { 
    throw new UnsupportedOperationException("Not serializable!!!"); 
} 

Hoặc bạn có thể thực hiện Externalizable và và viết thực hiện tương tự của writeExternal()

Cả hai đều không phương pháp "tốt" nhưng chỉ cách giải quyết.

1

Câu trả lời tôi thấy ở đây thực sự chỉ trả lời cho dù có thể ngăn việc tuần tự hóa hoặc deserialization của một số lớp được đánh dấu tuần tự. Câu hỏi là một câu hỏi khác, mặc dù:

'Có thể nói "Không, lớp này không thể tuần tự hóa được và tôi không muốn nó" theo cách mà bạn không nhận được bất kỳ lỗi trong các công cụ như Sonar? '

(Vì vậy, tôi tự hỏi về những nhiều up-phiếu trên những câu trả lời ...)

Google'ing quanh câu trả lời có vẻ là 'không', Sonar có thể được thông báo rằng một lớp học như là một "false tích cực ", nhưng điều đó đòi hỏi mày mò với Sonar. Các nhà phát triển phát triển mã kiểm tra bởi Sonar của người khác không thể hưởng lợi từ khả năng đó.Và như câu hỏi thực sự yêu cầu một giải pháp cho các công cụ khác "như Sonar", quá, câu trả lời nói chung không thể là "Có" --- chắc chắn rằng một số công cụ như vậy sẽ nhấn mạnh vào "thực hiện Serializable + có không- trường không có tuần tự không có thể tuần tự hóa "có nghĩa là sự cố.

+1

họ nhận được upvotes vì ​​họ đề xuất một giải pháp. – Matsemann

+0

Ồ, tôi thấy, các poster ban đầu đã thử nó và các công cụ trong câu hỏi thực sự tìm kiếm ngoại lệ đó. Vì vậy, câu trả lời thực sự ngụ ý một giải pháp ... – mkl

1

Bạn có thể sử dụng một cái gì đó như thế?

@SuppressFBWarnings(justification = "This field need to be transient") 
private transient SomeObject myTransientField; 

Bạn sẽ chặn cảnh báo Findbug. Bạn cũng có thể xác định loại xác nhận bạn muốn suprres như:

@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") 

Danh sách đầy đủ là có: http://findbugs.sourceforge.net/bugDescriptions.html

+0

Tôi thấy những gì bạn đang cố gắng để làm nhưng tôi chỉ có 'thoáng qua' bởi vì FindBugs phàn nàn về lĩnh vực không được serializable. Những gì tôi đang tìm kiếm là một cách để nói với Sonar rằng lớp học không thể và sẽ không được sắp xếp theo thứ tự. –

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