我想知道混合使用jdk 1.5和1.6(Java 6)对象序列化(biderctional communication)是否安全。我搜索了太阳关于这个问题的明确声明,但没有成功。因此,除了技术可行性之外,我正在寻找有关该问题的“官方”声明。
答案 0 :(得分:16)
序列化机制本身没有改变。对于个别课程,它将取决于具体的课程。如果类具有serialVersionUID字段,则应该指示序列化兼容性。
类似的东西:
private static final long serialVersionUID = 8683452581122892189L;
如果不变,则序列化版本兼容。对于JDK类,这是有保证的,但当然总是可能在进行重大更改后忘记更新serialVersionUID。
当JDK类不能保证兼容时,通常在Javadoc中提到它。
警告:此类的序列化对象与以后的Swing版本不兼容
答案 1 :(得分:3)
1.5和1.6中的序列化机制是兼容的。因此,在1.5和1.6上下文中编译/运行的相同代码可以交换序列化对象。两个VM实例是否具有相同/兼容的类版本(可能由serialVersionUID字段指示)是与JDK版本无关的另一个问题。
如果你有一个可序列化的Foo.java并在1.5和1.6 JDK / VM中使用它,那么由一个V创建的Foo的序列化实例;可以被另一个反序列化。
答案 2 :(得分:2)
在使用Java 1.5程序中的ObjectOutputStream将序列化对象写入文件进行测试之后,然后在Java 1.6程序中运行带有ObjectInputStream的读取,我可以说这没有任何问题。
答案 3 :(得分:2)
我会很快补充说,可以更改类但忘记来更改serialVersionUID。所以“如果类定义了一个serialVersionUID,并且没有改变,则保证类兼容是不正确的”。相反,具有相同的serialVersionUID是API承诺向后兼容的方式。
答案 4 :(得分:2)
除非另有说明,否则这应该是二进制兼容性的一部分。 Swing类在版本之间明显不兼容。如果您发现其他课程有问题,请报告bugs.sun.com上的错误。
答案 5 :(得分:2)
您是否阅读过Java Object Serialization Specification? versioning上有一个主题。还有一篇针对课程实施者的文章:Discover the secrets of the Java Serialization API。每个Java版本都附带compatibility notes。
关于序列化的Java 6规范:
目标是:
答案 6 :(得分:0)
请注意,Java Beans规范详细说明了与版本无关的序列化方法,该方法允许强大的向后兼容性。它还导致可读的“序列化”形式。实际上,使用该机制可以非常容易地创建序列化对象。
查看XMLEncoder
和XMLDecoder
类的文档。
我不会使用它来通过线路传递对象(虽然如果需要高性能,我也不会使用序列化)但它对于持久对象存储非常有用。
答案 7 :(得分:0)
混合使用Java 1.5和1.6是不安全的。例如,我将一个Java 1.5对象序列化为一个文件,并尝试在Java 1.6中打开它,但它提出了以下错误。
java.io.InvalidClassException: javax.swing.JComponent; local class incompatible: stream classdesc serialVersionUID = 7917968344860800289, local class serialVersionUID = -1030230214076481435
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)