什么是序列化和反序列化
- 序列化:对象——> 字节序列 (把对象转化成字节序列的过程)
- 反序列化:字节序列——> 对象 (把字节序列恢复为对象的过程)
为什么要序列化和反序列化
- 持久化对象:lightweight persistence 意味着对象的生命不是由程序决定的,在程序两次调用之间对象仍然或者;
- 网络传输:意味着序列化能够自动补偿操作系统方面的差异,就是说在window机器上创建的对象,序列化后,通过网络传输到UNIX机器上,进行反序列化后任然正确;
- RMI传输对象:远程方法调用(Remote Method Invocation),一种用于实现远程过程调用(RPC)(Remote procedure call)的Java API, 能直接传输序列化后的Java对象和分布式垃圾收集。它的实现依赖于Java虚拟机(JVM),因此它仅支持从一个JVM到另一个JVM的调用。
如何序列化
- 实现Serializable接口,这是一个标识接口
- 创建一个输出流OutputStream,然后将输出流嵌入到ObjectOutputStream流中;这时就可以用writeObject()方法将对象写入OutputStream流中;
例如:
new ObjectOutputStream(new FileOutputStream(new File("D:/test.txt"))).writeObject(new Serialize());
这里以将对象持久化话到文件中为例:
import java.io.*;
public class Serialize implements Serializable {
public void toSeria() throws IOException {
Serialize serialize = new Serialize();
File file = new File("D/test.txt");
//创建一个文件输出流,可以将数据写入到对应file引用的文件中;
FileOutputStream fos = new FileOutputStream("file");
//创建一个ObjectOutputStream写入指定的OutputStream。
ObjectOutputStream oOS = new ObjectOutputStream(fos);
//对象写入流中;
oOS.writeObject(serialize);
}
}
如何反序列化
创建一个输入流IutputStream,然后将输入流嵌入到ObjectIutputStream流中;这时就可以用readObject()方法将对象从IutputStream流中读取处理啊,读出来的Object型是需要转型;
(Serialize)( new ObjectInputStream(new FileInputStream(new File("D:/test.txt"))).readObject());
序列化时注意事项:
- static 修饰的属性不能被序列化:staic修饰的是类属性,对象不会将其系列化primitive
- transient修饰的属性不会序列化:有道翻译了一下transient是短暂那意思,那么用它修饰的字段,就是持久话对象时不用维护,也就是说那个字段不想序列化,就用它修饰就行了;
- 实现serializable接口时,一定要给这个serialVersionUID赋值:如果不设置的话Java会根据对象的属性去设置一个默认的serialVersionUID值,而在对类进行扩展时,反序列化得到旧数据时重新计算serialVersionUID,会发现不一致,就不能反序列化成功,也就会造成旧数据丢失
- 当属性是对象时,对象也要实现序列化接口;