2008-09-30 23 views
20

Tôi tự hỏi liệu có an toàn để trộn jdk 1.5 và 1.6 (Java 6) đối tượng tuần tự hóa (giao tiếp biderctional) hay không. Tôi đã tìm kiếm một tuyên bố rõ ràng từ mặt trời liên quan đến câu hỏi này nhưng không thành công. Vì vậy, bên cạnh tính khả thi về mặt kỹ thuật, tôi đang tìm kiếm một tuyên bố "chính thức" liên quan đến vấn đề này.Việc tuần tự hóa đối tượng java có tương thích giữa 1.5 và 1.6

+0

tôi biết đây là một câu hỏi cũ nhưng đối với các nhà phát triển trong tương lai, đây là một cái gì đó mà tôi đã sử dụng rộng rãi cho một sản phẩm với khách hàng, máy chủ sử dụng POJO trong vài năm. Các đối tượng được tuần tự hóa giữa các phiên bản đã hoạt động mà không có vấn đề gì. Lần duy nhất chúng tôi gặp sự cố là khi chúng tôi phá vỡ các quy tắc tuần tự hóa. Ví dụ: không thay đổi loại biến. –

Trả lời

2

Sau khi thử nghiệm với một đối tượng được tuần tự được ghi vào tệp bằng cách sử dụng ObjectOutputStream trong chương trình Java 1.5, sau đó chạy đọc với ObjectInputStream trong chương trình Java 1.6, tôi có thể nói điều này làm việc mà không có bất kỳ vấn đề nào.

+0

Không, bạn không thể. Bạn đã thử nghiệm nó cho một lớp học. Một nuốt không phải là mùa hè. – EJP

16

Cơ chế tuần tự không thay đổi. Đối với các lớp riêng lẻ, nó sẽ phụ thuộc vào lớp cụ thể. Nếu một lớp có trường serialVersionUID, điều này được cho là chỉ ra tính tương thích tuần tự hóa.

Cái gì như:

private static final long serialVersionUID = 8683452581122892189L; 

Nếu nó là không thay đổi, các phiên bản serialized tương thích. Đối với các lớp JDK, điều này được đảm bảo, nhưng dĩ nhiên bạn luôn có thể quên cập nhật serialVersionUID sau khi thực hiện thay đổi đột phá.

Khi lớp JDK không được đảm bảo tương thích, điều này thường được đề cập trong Javadoc.

Cảnh báo: đối tượng In nhiều của lớp này sẽ không tương thích với các phiên bản tương lai Swing

2

tôi sẽ nhanh chóng nói thêm rằng người ta có thể thay đổi lớp nhưng quên để thay đổi serialVersionUID. Vì vậy, nó là không chính xác rằng "Nếu lớp học định nghĩa một serialVersionUID, và điều này không thay đổi, lớp học được đảm bảo là tương thích." Thay vào đó, có cùng một serialVersionUID là cách một API hứa hẹn khả năng tương thích ngược.

+0

Tôi đã giả định câu hỏi là về các lớp jdk, và serialVersionUID của họ là chính xác ... – Tom

+0

Đủ công bằng: nếu nâng cấp JDK của bạn lộn xộn Serializable, các khách hàng của JDK cậu bé lớn của bạn (tức là Sun, BEA, IBM, vv) nên hét lên giết người đẫm máu (và tôi có). Phải thừa nhận rằng câu hỏi không rõ ràng cho dù đó chỉ là về các lớp JDK. – Alan

2

Trừ khi có quy định khác, điều này phải là một phần của khả năng tương thích nhị phân. Các lớp Swing rõ ràng không tương thích giữa các phiên bản. Nếu bạn gặp sự cố với các lớp khác, hãy báo cáo lỗi trên bugs.sun.com.

+0

Tính tương thích nhị phân là về giao diện công cộng và được bảo vệ, trong khi khả năng tương thích tuần tự tương ứng với các trường riêng tư thường. Bạn có chắc là người kia ngụ ý người kia không? – Tom

+0

Về mặt kỹ thuật, nó không tương thích nhị phân như được định nghĩa trong Chương 13 của JLS. Tuy nhiên khả năng tương thích nhị phân đối với serialization là bắt buộc giữa các phiên bản Java, trừ khi được chỉ định khác. Nếu bạn tìm thấy sự cố, hãy báo cáo lỗi. –

2

Bạn đã đọc Java Object Serialization Specification chưa? Có một chủ đề trên versioning. Ngoài ra còn có một bài viết cho người thực hiện lớp học: Discover the secrets of the Java Serialization API. Mỗi bản phát hành Java được kèm theo compatibility notes.

Từ Java 6 spec trên serialization:


Mục tiêu là: giao tiếp

  • Hỗ trợ hai chiều giữa các phiên bản khác nhau của một lớp đang hoạt động tại các máy ảo khác nhau bằng cách:
    • Xác định cơ chế cho phép các lớp JavaTM đọc luồng được viết bởi các phiên bản cũ của cùng một lớp.
    • Xác định cơ chế cho phép các lớp JavaTM ghi các luồng dự định được đọc bởi các phiên bản cũ của cùng một lớp.
  • Cung cấp tuần tự hóa mặc định cho sự kiên trì và cho RMI.
  • Thực hiện tốt và tạo luồng nhỏ gọn trong các trường hợp đơn giản, để RMI có thể sử dụng tuần tự hóa.
  • Có thể xác định và tải các lớp khớp với lớp chính xác được sử dụng để ghi luồng.
  • Giữ mức phí thấp cho các lớp không phiên bản.
  • Sử dụng định dạng luồng cho phép truyền tải luồng mà không cần phải gọi các phương thức cụ thể cho các đối tượng được lưu trong luồng.

3

Cơ chế serialization trong 1.5 và 1.6 tương thích. Do đó, cùng một mã được biên dịch/chạy trong một bối cảnh 1.5 và 1.6 có thể trao đổi các đối tượng được tuần tự hóa. Cho dù hai cá thể VM có phiên bản tương tự/tương thích của lớp (như có thể được chỉ định bởi trường serialVersionUID) là một câu hỏi khác không liên quan đến phiên bản JDK.

Nếu bạn có một Foo.java tuần tự hóa và sử dụng nó trong phiên bản 1.5 và 1.6 JDK/VM, các phiên bản Foo được tạo bởi một V; có thể được deserialized bởi người khác.

0

Lưu ý rằng đặc tả Java Beans chi tiết một phương pháp tuần tự độc lập phiên bản cho phép khả năng tương thích ngược mạnh mẽ. Nó cũng dẫn đến các biểu mẫu "được tuần tự hóa" có thể đọc được. Trong thực tế, một đối tượng serialized có thể được tạo ra khá dễ dàng bằng cách sử dụng cơ chế.

Tra cứu tài liệu về các lớp học XMLEncoderXMLDecoder. Tôi sẽ không sử dụng điều này để vượt qua một đối tượng trên dây nhất thiết (mặc dù nếu hiệu suất cao là một yêu cầu, tôi sẽ không sử dụng serialization hoặc), nhưng nó vô giá cho lưu trữ đối tượng liên tục.

0

Không an toàn khi kết hợp java 1.5 và 1.6. Ví dụ: tôi có một đối tượng java 1,5 được tuần tự hóa thành một tệp và đã thử mở bằng java 1.6 nhưng đã xảy ra lỗi bên dưới

java.io.InvalidClassException: javax.swing.JComponent; địa phương lớp tương thích: dòng classdesc serialVersionUID = 7917968344860800289, lớp địa phương serialVersionUID = -1030230214076481435 tại java.io.ObjectStreamClass.initNonProxy (Unknown Source) tại java.io.ObjectInputStream.readNonProxyDesc (Unknown Source) tại java.io.ObjectInputStream. readClassDesc (Unknown Source) tại java.io.ObjectInputStream.readNonProxyDesc (Unknown Source) tại java.io.ObjectInputStream.readClassDesc (Unknown Source) tại java.io.ObjectInputStream.readNonProxyDesc (Unknown Source) tại java.io. ObjectInputStream.readClassDesc (Nguồn không xác định) tại java.io.ObjectInputStream.readOrdinaryObject (Nguồn không xác định) tại java.io.ObjectInputStream.readObject0 (Nguồn không xác định) tại java.io.ObjectInputStream.readArray (Nguồn không xác định) tại java.io.ObjectInputStream.readObject0 (Nguồn không xác định) tại java.io.ObjectInputStream.defaultReadFields (Unknown Source) tại java.io.ObjectInputStream.readSerialData (Unknown nguồn) tại java.io.ObjectInputStream.readOrdinaryObject (Unknown Source) tại java.io.ObjectInputStream.readObject0 (Unknown Source) tại java.io.ObjectInputStream.defaultReadFields (Unknown Source) tại java.io.ObjectInputStream.readSerialData (Nguồn không xác định) tại java.io.ObjectInputStream.readOrdinaryObject (Nguồn không xác định) tại java.io.ObjectInputStream.readObject0 (Nguồn không xác định) tại java.io.ObjectInputStream.readArray (Unknown Source) tại java.io.ObjectInputStream.readObject0 (Unknown Source) tại java.io.ObjectInputStream.defaultReadFields (Unknown Source) tại java.io.ObjectInputStream.readSerialData (Unknown Source) tại java.io. ObjectInputStream.readOrdinaryObject (Unknown Source) tại java.io.ObjectInputStream.readObject0 (Unknown Source) tại java.io.ObjectInputStream.readObject (Unknown Source)

+0

Nó không an toàn * đối với lớp học cụ thể đó, * vì nó nêu rõ trong Javadoc của chính nó. Bạn đã không vấp phải một luật của vũ trụ ở đây. – EJP

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