天天看点

Java序列化

java序列化      是指把java对象转换为字节序列的过程;

java反序列化    是指把字节序列恢复为java对象的过程。

java 对象序列化是 jdk 1.1 中引入的一组开创性特性之一,用于作为一种将 java 对象的状态转换为字节数组,以便存储或传输的机制,以后,仍可以将字节数组转换回 java 对象原有的状态。

实际上,序列化的思想是 “冻结” 对象状态,传输对象状态(写到磁盘、通过网络传输等等),然后 “解冻” 状态,重新获得可用的 java 对象。所有这些事情的发生有点像是魔术,这要归功于 objectinputstream/objectoutputstream 类、完全保真的元数据以及程序员愿意用serializable 标识接口标记他们的类,从而 “参与” 这个过程。

java序列化的好处:

1. 是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里);

2. 是利用序列化实现远程通信,即在网络上传送对象的字节序列。

object serializalbe 优点:java原生支持,不需要提供第三方的类库,使用比较简单。

缺点:无法跨语言,字节数占用比较大,某些情况下对于对象属性的变化比较敏感。

java实现序列化的方法:

方法一:若student类仅仅实现了serializable接口;

方法二:若student类仅仅实现了serializable接口,并且还定义了readobject(objectinputstream in)和writeobject(objectoutputsteam out);

方法三:若student类实现了externalnalizable接口,且student类必须实现readexternal(objectinput in)和writeexternal(objectoutput out)方法,

对于实现java的序列化接口需要注意一下几点:

1. java中的序列化时transient变量(这个关键字的作用就是告知java我不可以被序列化)和静态变量不会被序列化。

2. 也是最应该注意的,如果你先序列化对象a后序列化b,那么在反序列化的时候一定记着java规定先读到的对象是先被序列化的对象,不要先接收对象b,那样会报错.尤其在使用 externalizable的时候一定要注意读取的先后顺序。

3. 实现序列化接口的对象并不强制声明唯一的serialversionuid,是否声明serialversionuid对于对象序列化的向上向下的兼容性有很大的影响。

4.java序列化有很多的要求,最主要的一个是包含能够序列化任何东西(或至少任何实现serializable接口)。这样才能进入其他jvm之中,这很重要,所以有时性能不是主要的要求,标准的格式才最重要。

5.通过实现externalizable接口,这是可能优化java序列化的。实现此接口,避免写出整个类定义,只是类名被写入。它需要你实施readexternal和writeexternal方法方法的,所以需要做一些工作,但相比仅仅是实现serializable更快,更高效。externalizable对小数目对象有效的多。但是对大量对象,或者重复对象,则效率低。

serialversionuid

如果没有明确指定serialversionuid,序列化的时候会根据字段和特定的算法生成一个serialversionuid,当属性有变化时这个id发生了变化,所以反序列化的时候就会失败。抛出“本地classd的唯一id和流中class的唯一id不匹配”。

jdk文档关于serialversionuid的描述:

如果可序列化类未显式声明 serialversionuid,则序列化运行时将基于该类的各个方面计算该类的默认 serialversionuid 值,如“java(tm) 对象序列化规范”中所述。不过,强烈建议所有可序列化类都显式声明 serialversionuid 值,原因是计算默认的 serialversionuid 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 invalidclassexception。因此,为保证 serialversionuid 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialversionuid 值。还强烈建议使用 private 修饰符显示声明 serialversionuid(如果可能),原因是这种声明仅应用于直接声明类 -- serialversionuid 字段作为继承成员没有用处。数组类不能声明一个明确的 serialversionuid,因此它们总是具有默认的计算值,但是数组类没有匹配 serialversionuid 值的要求。