参考:
http://www.blogjava.net/jiangshachina/archive/2012/02/13/369898.html
http://www.importnew.com/24490.html
https://blog.csdn.net/jason_279/article/details/52947093
1. 什么是Java对象序列化
Java平台允许我们在内存中创建可复用的Java对象,但是,只有JVM处于运行时,这些对象才存在。但是在现实应用中,可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来(如:被其他JVM)重新读取被保存的对象。Java对象序列化,可以完成上述任务,Java序列化API为处理对象的序列化提供了一个标准机制。
使用Java对象序列化,在保存对象时,会将对象的域(即成员变量,不会关注类中的静态变量)保存为一组字节(也就是二进制文件),这个过程称为对象序列化。在未来,再将这些字节组装成对象,这个过程称为反序列化。
除了在持久化对象的应用场景中会使用到对象序列化之外,RMI(远程方法调用)或在网络中传输对象的应用场景中也会使用到对象的序列化。
JDK默认序列化机制
使用JDK提供的序列化机制必须满足的条件:
- 该类或者间接从其继承树(父类)中必须实现java.io.Serializable接口;
- 不被序列化的域必须要使用transient关键字:包含主观不想序列化的域和本身没有实现序列化的类型(如:Thread类型的域)对应的域;
JDK提供的默认序列化机制是通过一对I/O流ObjectOutPutStream和ObjectInputStream进行序列化和反序列化操作,使用ObjectInputStream.writeObject(NeedSerializedObject)方法进行对象序列化,把对象写入到输出流中。使用ObjectInputStream.readObject()进行反序列化,从输入流中反序列化出对象。(实例参考上述博客)
影响序列化
由于JDK提供的默认序列化机制,是简单的将对象转换为字节流,JDK还提供了扩展方法可以对序列化和反序列化进行控制。如:序列化时,某些字段需要进行加密、没必要保存或者忽略掉敏感数据等,就不用进行序列化。反序列化时,需要对某些transient(没有被序列化的)字段赋初值等。
- 使用transient关键与在NeedSerializedClass定义私有方法:writeObject和readObject方法。PS:在调用ObjectOutputStream.writeObject和ObjectOutputStream.readObject时,序列化和反序列化机制会把控制流转交给自定义的私有方法writeObject和readObject方法。自定义的writeObject和readObject方法中必须分别调用ObjectOutputStream.defaultWriteObject和ObjectInputStream.defaultReadObject方法。
- Externalizable接口:不继承Serializable接口,继承Externalizable接口。(实例参考上述博客)