java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java序列化的原理

Java序列化的原理分析及解决

作者:赚够壹仟万

文章介绍了Java中的序列化机制,包括Serializable和Externalizable接口的区别,以及serialVersionUID的作用,Serializable接口可以序列化的所有子类型本身都是可序列化的,如果要序列化的类有父类,父类也应该实现Serializable接口

概念

序列化是指将对象转换为可传输格式的过程。是一种数据持久化手段。

在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不同。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文