序列化的限制

时间:2014-04-24 14:06:44

标签: java serialization

我创建了一个带有两个int变量的简单类,它实现了Serializable接口。然后我为这个类创建了对象,并在我的本地文件系统中使用ObjectOutputStream进行了序列化。现在关键在于序列化后我通过删除一个变量修改了serilized类。

现在当我尝试反序列化对象时,它会抛出一个名为“java.io.InvalidClassException”的异常。

有没有办法限制修改序列化类。

这种情况在java /编程术语中称为什么。

先谢谢。

我的代码如下:

package sample;

import java.io.Serializable;

public class Serial implements Serializable{
    int a,b;
    public void disp(){
        System.out.println(a+"        "+b);
    }
}


package sample;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ser {

    public static void main(String[] args) {
        Serial ss=new Serial();
        ss.a=10;
        //ss.b=20;
        try{
            FileOutputStream fio=new FileOutputStream("D:\\abc.ggg");
            ObjectOutputStream oos=new ObjectOutputStream(fio);
            oos.writeObject(ss);
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }

}

package sample;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class Dser {

    public static void main(String[] args) {
        try {
            FileInputStream fis=new FileInputStream("D:\\abc.ggg");
            ObjectInputStream ois=new ObjectInputStream(fis);
            Serial sss=(Serial)ois.readObject();
            sss.disp();
            System.out.println(sss.a+"    ");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

2 个答案:

答案 0 :(得分:0)

每个可序列化类都有一个关联的serialVersionUID。像

private static final long serialVersionUID = 1L;  

要么提供它,要么JVM会在序列化类的实例时对其进行计算。通常,在修改类时,可以修改此ID,以便匹配类版本。当您不提供ID时,计算出的ID正在考虑您的实例变量,因此如果您更改类,这将是不同的,这是您获得java.io.InvalidClassException的原因之一。

现在当你改变你的类时,即在你的情况下删除一个变量,你的文件中的序列化类仍然有旧的类实例。当它被反序列化时,实例状态从文件中提取并尝试使用 Reflection 注入新创建的对象。现在,当它尝试注入你已删除的变量的值时,它将抛出异常。

答案 1 :(得分:0)

我认为限制更改序列化类的最佳方法是通过javadoc和测试的组合。换句话说,你不能严格执行,没有人改变它,但你可以肯定强烈建议他们除非他们已经考虑过后果。

当你序列化一个类时,你可能会想要成为你的公共API的一部分而且你会被永远地锁定它。如果你还没有,我建议你查看Josh Bloch的书中的序列化章节" Effective Java" - 项目74-78。他进入了你可能遇到的无数陷阱以及如何避免其中的大量陷阱。