一、 何为序列化
序列化就是将一个实例数据对象写入输入流中然后持久化到数据库或者文件系统中,或者转换为字符串。
反序列化则是将经过序列化后持久化的数据或者字符串转换为实例数据对象。
二、 为什么要序列化
1) 远程消息调用
从一个应用中将一个数据对象传给另一个应用时需要将对象转换为输入流或者字符串。
2) 降低IO操作。
如将彩信附件包转换为彩信附件对象时,不仅要有流的操作还需要构建附件对象都是极为耗时的,某种场景需要将彩信附件存储到数据库系统或者文件系统时,如果存储的是彩信附件包那么需要先转换为流再构建耗时较长,如果直接将彩信附件对象序列化后存储,调用时只需要反序列化就可以得到彩信附件对象则会效率较高。
3) 序列化时对敏感字段加密
在序列化的对象中添加writeObject 和 readObject方法,在这两个方法中进行特殊处理。
三、 序列化的实现
将需要被序列化的类实现Serializable接口,然后使用一个输出流(如:FileOutputStream)将数据对象构造一个ObjectOutputStream对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
四、 序列化的控制
1) 如果某个类能够被序列化,其子类也可以被序列化。如果该类有父类,则分两种情况来考虑,如果该父类已经实现了Serializable接口。则其父类的相应字段及属性的处理和该类相同;如果该类的父类没有实现Serializable接口,则该类的父类所有的字段属性将不会串行化。
2) 声明为static和transient类型的成员属性不能被序列化,因为static代表类的状态, transient代表对象的临时数据。
五、 序列化开源框架
bboss、xStream、kryo等
六、 代码案例
1. 原生态序列化
package serialize;
import java.io.*;
publicclass SerializeTest implements Serializable {
private String name;
public String getName() {
returnthis.name;
}
publicvoid setName(String name) {
this.name = name;
}
publicstaticvoid main(String[] args) {
SerializeTest test = new SerializeTest();
try {
FileOutputStream fos = new FileOutputStream("D:\\1.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
test.setName("My SerializeTest");
oos.writeObject(test);
oos.close();
} catch (Exception ex) {
ex.printStackTrace();
}
try {
FileInputStream fis = new FileInputStream("D:\\1.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
test = (SerializeTest) ois.readObject();
System.out.println(test.getName());
ois.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public String toString() {
return"name=" + name;
}
}
2. XStream注解
publicclass XstreamUtil {
publicstatic String objectToXml(Object obj) {
XStream xStream = new XStream();
xStream.processAnnotations(obj.getClass());
return xStream.toXML(obj);
}
publicstatic <T> T xmlToObject(String xml, Class<T> cls) {
XStream xstream = new XStream(new DomDriver());
xstream.processAnnotations(cls);
return (T) xstream.fromXML(xml);
}
}