举例说明序列化常见问题
1.例子,将OrderTimeCostDTO的对象序列化,再反序列化
@Test
public void m1() throws IOException, ClassNotFoundException {
OrderTimeCostDTO otc =OrderTimeCostDTO.builder().cutTime(new Date()).build();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:\\stu.txt"));
oos.writeObject(otc);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:\\stu.txt"));
OrderTimeCostDTO o = (OrderTimeCostDTO)ois.readObject();
log.info(o+"");
ois.close();
}
打印结果:
OrderTimeCostDTO(cutTime=Tue Apr 14 15:52:06 CST 2020,...)
2.现在修改OrderTimeCostDTO类,多加一个参数
public class OrderTimeCostDTO implements Serializable{
/**
* 多加一个aa参数
*/
private Date aa;
...
}
3.将d:\stu.txt中的数据反序列化
@Test
public void m1() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:\\stu.txt"));
OrderTimeCostDTO o = (OrderTimeCostDTO)ois.readObject();
log.info(o+"");
ois.close();
}
结果:
java.io.InvalidClassException: com.baturu.tms.api.dto.transport.OrderTimeCostDTO;
local class incompatible: stream classdesc serialVersionUID = -350958361371879346, local class serialVersionUID = -2789788224825224853
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687)
...
解释
将一个对象序列化时,程序会生成一个serialVersionUID
这个serialVersionUID会因为各种原因发生变化,例如类的属性或方法变化,SDK版本的变化等等
所以当我们将类多加一个参数时,serialVersionUID发生了变化,所以将d:\stu.txt文件中的对象对映的serialVersionUID与本地serialVersionUID做比较时
,发现不一致,报错。
其中model来自反序列化文件时拿到的ObjectStreamClass,osc为反序列化时得到的类的ObjectStreamClass,ObjectStreamClass可以理解为类的描述,包括参数等等,
具体可以看下序列化的源码,推荐:https://blog.csdn.net/u011315960/article/details/89963230
建议手动设置serialVersionUID
,兼容类发生的变化,如果没有手动设置serialVersionUID,会根据系统算法默认生成一个serialVersionUID。系统生成的serialVersionUID会因为各种原因发生变化,例如类的属性或方法变化,SDK版本的变化等等,所以加字段很容易反序列化失败。
建议使用JSON传输数据
,可读性更强,效率更高