对象的字节序列存在硬盘上,更改了类的属性,反序列化时会造成不兼容问题。“但当serialVersionUID相同时,它就会将不一样的field以type的预设值反序列化,可避开不兼容问题”这句话什么意思?
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)。
可以编写测试类:
import java.io.Serializable;
public class Serial implements Serializable {
private static final long serialVersionUID = 6977402643848374753L;
int id;
String name;
public Serial(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "DATA: " + id + " " + name;
}
}
序列化测试代码:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerialTest {
public static void main(String[] args) {
Serial serial1 = new Serial(1, "song");
System.out.println("Object Serial" + serial1);
try {
FileOutputStream fos = new FileOutputStream("serialTest.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(serial1);
oos.flush();
oos.close();
} catch (FileNotFoundException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
}
}
反序列化测试代码:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserialTest {
public static void main(String[] args) { // TODO Auto-generated method stub
Serial serial2;
try {
FileInputStream fis = new FileInputStream("serialTest.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
serial2 = (Serial) ois.readObject();
ois.close();
System.out.println("Object Deserial" + serial2);
} catch (FileNotFoundException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
}
}
可以测试待序列化类Serial设置了版本号,分别运行SerialTest和DeserialTest类后,如果修改Serial类添加一个属性int age,那么再执行DeserialTest的时候还是能够正确运行的。但是如果注释掉版本号后,就会报不兼容异常了,因为我们运行SerialTest序列化时类信息没变更之前的版本号是A,然后修改Serial类的版本号后,并修改了类的属性信息。再执行反序列话时发现读取的字节码信息中的序列号与当前类的版本号不同,所以会任务前后类型版本不一样,有变更,所以报运行时异常了。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。