我从概念上理解 Java 序列化,但是我对可序列化对象的版本兼容性感到非常困惑。当提到“版本”时,它是否意味着:
是否存在层级关系的两个类,且其中一个类有属性的加/减?
或者两个类遵循不同的编译版本?
还是两者都有?
我的理解是我们必须保持suid一致,这是由JVM检查版本兼容性的。
因此我设计了一个实验来测试java序列化的版本不兼容问题,代码片段如下,其中我将suid改成了不同的:
public static class Incompatible implements Serializable {
private static final long serialVersionUID = 1L;
private int i;
public Incompatible(int i){
this.i = i;
}
public int getI(){
return i;
}
}
public static class IncompFoo extends Incompatible {
private static final long serialVersionUID = 2L;
public IncompFoo(int i){
super(i);
}
}
@Test
public void incompatibleTest() throws IOException, ClassNotFoundException{
FileOutputStream fos = new FileOutputStream(new File("foo.ser"));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(new IncompFoo(10));
oos.close();
FileInputStream fis = new FileInputStream(new File("foo.ser"));
ObjectInputStream ois = new ObjectInputStream(fis);
Incompatible foo = (Incompatible)ois.readObject();
ois.close();
Assert.assertEquals(10, foo.getI());
}
我预计会出现 InvalidClassException,因为这两个类具有不同的 suid。令我惊讶的是,测试顺利通过。
哪一部分是错误的?我们有一个简单的方法来创建 InvalidClassException 吗?
最佳答案
您的示例写入一个对象,读取它并将其转换为其父类(super class)。那里没有发生任何有趣的事情,即使您希望 Actor 会以某种方式破坏事情(它没有,它只是一个 Actor 和一个有效的 Actor )。
将类的实例写入文件,更改其serialVersionUID
,重新编译该类并尝试读回序列化对象。忘记任何父类(super class)/子类恶作剧。
关于java - 实验Java序列化的不兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38188027/