java - 实验Java序列化的不兼容性

标签 java serialization version compatibility

我从概念上理解 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/

相关文章:

JAVA浮点运算

c# - 如何将 Observables 序列化到云端并返回

php - 按降序对一组软件版本进行排序

Java文档createElement错误

java - 在java中将byte[]数组从MySQL转换为带有破折号的十六进制?

java - Spark序列化和Java序列化有什么区别?

version - 在 Chef 客户端运行期间提取 Recipe 名称和版本

.net - 从.NET 1.1迁移到.NET 3.5

java - 如何在java中创建自定义数据类型?

python - `pandas to_json` 和 `read_json` 之间的文件大小差异较大