试验目的:哪些情况会导致java反序列化失败。
持久化到本地
public class Test {
private static String file = "/serialFile.txt";
public static void main(String[] args)throws Exception {
write();
//read();
}
static void write() throws Exception{
FileOutputStream os = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(os);
Student s = new Student();
s.setAge(20);
s.setName("test");
s.setState(State.TEST);
oos.writeObject(s);
oos.close();
}
static void read() throws Exception{
FileInputStream is = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(is);
Student s = (Student)ois.readObject();
System.out.println(s);
}
}
class Student implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
State state;
String name;
String id;
int age;
public void setState(State state) {
this.state = state;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String toString(){
StringBuffer str = new StringBuffer();
str.append("state:").append(state != null ? state.getValue() : "error").append(" ");
str.append("name:" + name).append(" ");
str.append("age:" + age).append(" ");
str.append("id:" + id);
return str.toString();
}
}
public enum State {
COMMON(1),TEST(2);
private int value;
private State(int value){
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
1.枚举类型实例删除,反序列化会有问题
//将 Test实例删除
public enum State {
COMMON(1);
private int value;
private State(int value){
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
Exception in thread "main" java.io.InvalidObjectException: enum constant TEST does not exist in class com.my.test.serializable.State
at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1704)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1326)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at com.my.test.serializable.Test.read(Test.java:34)
at com.my.test.serializable.Test.main(Test.java:16)
Caused by: java.lang.IllegalArgumentException: No enum const class com.my.test.serializable.State.TEST
at java.lang.Enum.valueOf(Enum.java:196)
at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1702)
... 8 more
2.减少一个属性,和方法,执行read() ,不会有问题
减少以下代码
String name;
public void setName(String name) {
this.name = name;
}
3.增加属性和方法,执行read(),不会有问题
//增加
String id;
//增加
public String getId() {
return id;
}
//增加
public void setId(String id) {
this.id = id;
}
4.将private static final long serialVersionUID = 1L;变成2,执行read()
Exception in thread "main" java.io.InvalidClassException: com.my.test.serializable.Student;
local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at com.my.test.serializable.Test.read(Test.java:34)
at com.my.test.serializable.Test.main(Test.java:16)
部分结论:
1.反序列化时如果是减少或增加属性(包括枚举),方法,不会有问题
2.如果要反序列化枚举实例时,程序端有该枚举类型但没有该实例,则抛错。
3.如果反序列化时,程序端原枚举类型增加了新的实例且原实例存在,不会抛错.
4.序列化版本号不对,抛错。