Java序列化的原理分析及解决
作者:赚够壹仟万
概念
序列化是指将对象转换为可传输格式的过程。是一种数据持久化手段。
在Java的序列化机制中,如果是String,枚举或者是实现了Serializable接口的类,均可以通过Java的序列化机制,将类序列化为符合编码的数据流,然后通过InputStream和OutputStream将内存中的类持久化到硬盘或者网络中。
Serializable 和 Externalizable 接口有何不同?
Serializable接口可序列化的所有子类型本身都是可序列化的。
如果要序列化的类有父类,要想将父类中的变量也持久化下来,那么父类也应该实现Serializable接口。
Externalizable继承了Serializable,该接口定义了两个方法,当使用Externalizable接口来进行序列化和反序列化时需要重写这两个方法,如果没有定义具体的序列化细节,那么序列化之后的对象为空。
serialVersionUID有什么用?没定义会有什么问题?
虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的点是两个类的序列化ID是否一致。也即serialVersionUID一致。
在进行反序列化时,JVM会把传来的字节流中的seriaVersionUD与本地相应实体类的seriaIVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。这样做是为了保证安全,因为文件存储中的内容可能被篡改。
注意:如果在使用时不去定义SerialVersionUID,如果在序列化对象之后修改了这个类的信息(例如加一个字段)那么反序列会失败,因为会存在两个不同的SerialVersionUID.
class User implements Serializable{ private String name; }
如果定义了一个上述类的对象并保存到文件中(这里没有指定SerialVersionUID)。
然后修改这个类,增加一个属性。
class User implements Serializable{ private String name; private int age; }
执行反序列化时就会抛出一个InvalidClassException,并且指出两个serialVersionUID不同。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。