Java系列化不兼容的实验

Java系列化不兼容的实验,java,serialization,version,compatibility,Java,Serialization,Version,Compatibility,我从概念上理解Java序列化,但是我对可序列化对象的版本兼容性非常困惑。当提及“版本”时,是否意味着: 一个层次关系的两个类中的任何一个,其中一个具有属性的加/减 还是两个类遵循不同的编译版本 或者两者都有 我的理解是,我们必须保持suid的一致性,这是由JVM检查版本兼容性的 因此,我设计了一个实验,试图测试java序列化的版本不兼容性,代码片段如下,其中我使suid有所不同: public static class Incompatible implements Serializab

我从概念上理解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());

}
由于这两个类具有不同的suid,所以我需要一个InvalidClassException。令我惊讶的是,考试顺利通过了


哪一部分错了?我们有创建InvalidClassException的简单方法吗?

您的示例编写一个对象,读取它并将其强制转换为其超类。那里没有什么有趣的事情发生,尽管你希望演员阵容会以某种方式打破现状(事实并非如此,这只是一个演员阵容,一个有效的阵容)


将类的实例写入该文件,更改其
serialVersionUID
,重新编译该类并尝试读回序列化对象。忘记任何超级/子类的诡计。

你必须用与你所写的不同版本的同一类来阅读。您尚未更改类的代码,因此不应期望出现问题。您需要学习对象序列化规范中的对象版本控制章节。