Java 对象序列化为二进制文件的技术是 Java 系列技术中一个较为重要的技术点,在大多数情况下,只需要了解被序列化的类需要实现 Serializable 接口,使用 ObjectInputStream 和 ObjectOutputStream 进行序列化和反序列化即可。
在工作中,经常会碰到序列化的情况,因为我们调用的东西不可能都在本地,往往需要通过RMI,一些远程接口调用。这样数据序列化的技术更显得重要。而java序列化技术为我们实现这些远程调用提供了技术保障。
一. 序列化的ID,请看如下代码
片段一:
片段二:
两个类除了serialVersionUID,其余完全一样,但这两个类是不能被序列化与反序列化的,所以在写程序时,实现了序列化的类,serialVersionUID一定要一致,否则客户端与服务端将不匹配,会因serialVersionUID不匹配导致意想不到的问题。当然也可以通过服务端强制更新serialVersionUID值,让客户端主动报错,来强制更新程序。
二.子类实现Serializable接口,而父类并没有实现Serializable 接口
父类:Person.java
子类:Student.java
做如下测试:
运行结果:
结论:
1. 声明为 transient 型的属性是不被序列化的。
2. S_T属性的值被改变了,本来是序列时保存进去的是"static属性不能被序列化“,但读出来发现该值被改变,说明static声明的属性并没有 被写进文件里,所以声明为static型的属性是不被序列化的。
3. 子类实现Serializable接口,父类未实现Serializable接口,反序列化时父类的属性会被恢复成原始值,即int 0 ,String null.
父类必须有无参的构造方法,因为如果父类实现了Serializable接口,则会直接从序列化过的文件里反序列化,读出来原来的对象即可,
但若父类没有实现Serializable接口,则无法直接读取,所以只有调父类的默认构造器创建出该类的对象,再进行属性填充。
三.父类实现了Serializable接口的情况较简单,只需记住规则,如果父类实现了Serializable接口,则子类默认也可被序列化,不需要显式声明Serializable接口。