Java 对序列化的限制
我创建了一个带有两个int变量的简单类,它实现了可序列化接口。然后,我为这个类创建了对象,并在本地文件系统中使用ObjectOutputStream进行序列化。现在重点是序列化之后,我通过删除一个变量修改了序列化类 现在,当我尝试反序列化对象时,它抛出了一个名为“java.io.InvalidClassException”的异常 那么有没有办法限制对序列化类的修改呢 这个场景在java/编程术语中叫什么 提前谢谢 我的代码如下:Java 对序列化的限制,java,serialization,Java,Serialization,我创建了一个带有两个int变量的简单类,它实现了可序列化接口。然后,我为这个类创建了对象,并在本地文件系统中使用ObjectOutputStream进行序列化。现在重点是序列化之后,我通过删除一个变量修改了序列化类 现在,当我尝试反序列化对象时,它抛出了一个名为“java.io.InvalidClassException”的异常 那么有没有办法限制对序列化类的修改呢 这个场景在java/编程术语中叫什么 提前谢谢 我的代码如下: package sample; import java.io.S
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();
}
}
}
每个可序列化类都有一个关联的
serialVersionUID
。像
private static final long serialVersionUID = 1L;
要么提供它,要么JVM在序列化类实例时计算它。通常,当您修改类时,您会修改此ID,以便匹配类版本。当您不提供ID时,计算的ID会考虑到您的实例变量,因此如果您更改类,则会有所不同,这是您获得java.io.InvalidClassException
的原因之一
现在,当您更改您的类,即删除案例中的变量时,文件中的序列化类仍然具有旧的类实例。反序列化后,将从文件中提取实例状态,并尝试使用反射注入新创建的对象。现在,当它尝试注入您删除的变量的值时,它将抛出异常。我认为限制序列化类更改的最佳方法是通过javadoc和测试的组合。换句话说,你不能严格要求没有人改变它,但你可以强烈建议他们不要,除非他们考虑过后果
当您序列化一个类的次数远远超出您的预期时,它将成为公共API的一部分,并且您将永远被它锁定。如果您还没有,我建议您查看Josh Bloch的《有效Java》一书中的序列化章节——第74-78项。他会遇到无数陷阱,以及如何避免这些陷阱。请显示相关代码。完成这些代码后,不要忘记关闭资源