Java系列化不兼容的实验
我从概念上理解Java序列化,但是我对可序列化对象的版本兼容性非常困惑。当提及“版本”时,是否意味着: 一个层次关系的两个类中的任何一个,其中一个具有属性的加/减 还是两个类遵循不同的编译版本 或者两者都有 我的理解是,我们必须保持suid的一致性,这是由JVM检查版本兼容性的 因此,我设计了一个实验,试图测试java序列化的版本不兼容性,代码片段如下,其中我使suid有所不同:Java系列化不兼容的实验,java,serialization,version,compatibility,Java,Serialization,Version,Compatibility,我从概念上理解Java序列化,但是我对可序列化对象的版本兼容性非常困惑。当提及“版本”时,是否意味着: 一个层次关系的两个类中的任何一个,其中一个具有属性的加/减 还是两个类遵循不同的编译版本 或者两者都有 我的理解是,我们必须保持suid的一致性,这是由JVM检查版本兼容性的 因此,我设计了一个实验,试图测试java序列化的版本不兼容性,代码片段如下,其中我使suid有所不同: public static class Incompatible implements Serializab
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
,重新编译该类并尝试读回序列化对象。忘记任何超级/子类的诡计。你必须用与你所写的不同版本的同一类来阅读。您尚未更改类的代码,因此不应期望出现问题。您需要学习对象序列化规范中的对象版本控制章节。