2010-09-07 31 views
7

Cũng giống như tựa đề, có cách nào để kiểm tra xem một đối tượng có thể tuần tự hóa không và nếu không, hãy làm như vậy trong thời gian chạy?Bạn có thể tạo một đối tượng có thể tuần tự hóa trong thời gian chạy không?

+0

Nếu đối tượng không được nối tiếp, có thể có lý do chính đáng: ví dụ, rất ít khi nối tiếp kết nối cơ sở dữ liệu. –

+1

Định dạng tuần tự hóa không phải là Java Object Serialization có hoạt động không? Tôi đang nghĩ đến một giải pháp sử dụng sự phản chiếu và JSON hoặc XML để tuần tự hóa đối tượng. Từ những nhận xét khác, có vẻ như yêu cầu của bạn là biến đối tượng thành một String và điều này sẽ thực hiện điều đó. –

+0

Câu hỏi này thực sự rộng, chủ yếu bởi vì nó không đề cập đến tất cả các ràng buộc thiết kế của bạn. (Ví dụ: bạn cần định dạng tuần tự chuỗi.) – jpaugh

Trả lời

11

Trả lời ngắn gọn - không.

Câu trả lời dài hơn - có, sử dụng thao tác mã byte, ví dụ như với asm. Nhưng bạn nên thực sự xem xét liệu điều này là cần thiết. Serialization là một vấn đề nghiêm trọng (Effective Java có cả một chương về serialization)

Btw, có giải pháp thay thế để serialization nhị phân, mà không yêu cầu các đối tượng thực hiện Serializble (như được chỉ bởi Jacob trong các ý kiến):

  • XML - java.beans.XMLEncoder.encode(..) là phiên bản xml của ObjectOutputStream
  • JSON - khung như Jacskon, Gson cho phép bạn sắp xếp từng đối tượng bằng một dòng.
+0

+1 để bao gồm cảnh báo thích hợp. – DJClayworth

1

Như những người khác đã nói ... Ngắn trả lời là số

Bạn hoàn toàn có thể thêm một giao diện cho bất kỳ đối tượng cũ trong thời gian chạy bằng cách sử dụng đối tượng Proxy như đã mô tả ở http://download.oracle.com/javase/6/docs/technotes/guides/reflection/proxy.html. Điều này bao gồm java.io.Serializable quá. Tuy nhiên, để cho một đối tượng proxy có ích, nó phải duy trì một tham chiếu nội bộ đối tượng ban đầu, mà trong trường hợp của bạn không thực hiện Serializable. Cách duy nhất đối tượng proxy của bạn có thể được tuần tự hóa là bằng cách làm cho tham chiếu nội bộ đến đối tượng gốc một trường thoáng qua và điều đó sẽ không làm bạn tốt chút nào.

Hơn nữa, sau khi kiểm tra nhận xét của bạn, có vẻ như tuần tự hóa java chắc chắn không phải là những gì bạn muốn và bạn thực sự chỉ muốn tuần tự hóa thành một số định dạng chuỗi. Những người khác đã đề xuất các giải pháp khác nhau, nhưng IMO nếu bạn muốn số tiền ít phiền toái nhất, hãy đi với XStream: http://x-stream.github.io/tutorial.html.

+0

Proxy được tạo bởi giao diện chứ không phải trên lớp. – Bozho

+0

@Bozho - phần đó được trình bày chi tiết trong tài liệu tôi liên kết. Nó sẽ yêu cầu một số thay đổi trong codebase của mình nếu anh ta chưa sử dụng Giao diện để đa hình (sp?) Tham chiếu đến các đối tượng của mình. – whaley

+1

Đối tượng ban đầu của anh ta sẽ là thành viên của InvocationHandler, cũng được sắp xếp theo thứ tự, sẽ bị lỗi. – Bozho

0

Whoa. Tại sao bạn cần nó để được kiểm tra trong thời gian chạy? Không phải là nó dễ dàng hơn để đảm bảo nó tại thời gian biên dịch? Sử dụng một mã như thế này.

public void someMethod(Serializable serializable){ 
} 

Hoặc bạn có thể làm cho nó phức tạp hơn.

public interface SerializableInterface implements Serializable{ 
// bla-bla 
} 

public void someMethod(SerializableInterface serializable){ 
} 
0

Bên cạnh câu trả lời tốt hiện có, một câu hỏi khác là liệu bạn đặc biệt cần Java Serializable cho khuôn khổ cụ thể, hoặc chỉ cần để có thể đối tượng serializer. Đối với sau này có nhiều sự lựa chọn nhiều hơn JDK mặc định một; và đối với nhiều trường hợp sử dụng lựa chọn thay thế là tốt hơn nhiều so với JDK một.

Nếu bạn không cần JDK cụ thể, việc sử dụng chuỗi tuần tự dựa trên JSON hoặc XML thường là lựa chọn tốt.

+0

Lý do tôi xem xét tuần tự hóa là cho một dự án tôi muốn chuyển đổi một đối tượng thành một chuỗi (thông qua một mảng byte) để lưu trữ và truyền dẫn, nơi nó được yêu cầu là một String do các yếu tố bên ngoài. Tôi đã nhìn thấy một số ví dụ về cách sử dụng serialization để chuyển đổi sang một dòng byte để nắm bắt các đối tượng như là một String cuối cùng, nhưng không có gì trên phải làm gì nếu đối tượng không serializable. Tôi hiểu sự cần thiết của một số đối tượng không được tuần tự hóa, nhưng trong trường hợp này, nó sẽ là thứ gì đó trái với ý của nhà phát triển. –

+0

Ok, sau đó bạn chắc chắn KHÔNG muốn sử dụng JDK Serializable. Tôi sẽ khuyên bạn nên sử dụng JSON serialization (như Jackson, xem http://wiki.fasterxml.com/JacksonInFiveMinutes). Kết quả dễ đọc hơn và ít dễ vỡ hơn. Vấn đề chính với Serializable là phiên bản rất khó, vì vậy nó là một kết quả chống mẫu để duy trì kết quả (đọc lời giải thích của Josh Bloch, ví dụ). Nó không thể đọc được, hoặc là (không giống như xml hay json). Không có gì sai trong việc tuần tự hóa mọi thứ, nhưng Serializable ít khi đúng cách. – StaxMan

0

Kiểm tra tại thời gian chạy? Chắc chắn rồi. "if (someObject instanceof Serializable) ...".

Bạn muốn thay đổi định nghĩa của đối tượng trong thời gian chạy? Có rất hiếm khi một lý do tốt để muốn làm điều này. Có lẽ có một cách để làm điều này với sự phản chiếu, nhưng tôi chưa bao giờ có lý do để muốn làm một điều như vậy. Bạn đang cố gắng để thực hiện?

0

Nếu ai đó thực sự thực sự cần thao tác với bytecode trong thời gian chạy.Với thư viện Javassist có thể thực hiện việc này:

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("mypackage.MyClass"); 
cc.addInterface(pool.get("java.io.Serializable")) 
Các vấn đề liên quan