序列化Serializable和Externalizable的区别

大家都知道Serializable是一个mark interface,告诉JVM这个对象可以被转换成二进制流来传输.

但是Serializable与Externalizable的转换二进制流的过程是不一样的.

Serializable 在我们实现这个接口的时候,我们可以使用4个私有方法来控制序列化的过程:

我们来看一个例子:

Java代码  

  1. public class FooImpl implements java.io.Serializable{
  2. private String message;
  3. public String getFoo() {
  4. return message;
  5. }
  6. public void setMessage(String message) {
  7. this.message = message;
  8. }
  9. private void writeObject(java.io.ObjectOutputStream out) throws IOException {
  10. System.out.println("writeObject invoked");
  11. out.writeObject(this.message == null ? "hohohahaha" : this.message);
  12. }
  13. private void readObject(java.io.ObjectInputStream in) throws IOException,
  14. ClassNotFoundException {
  15. System.out.println("readObject invoked");
  16. this.message = (String) in.readObject();
  17. System.out.println("got message:" + message);
  18. }
  19. private Object writeReplace() throws ObjectStreamException {
  20. System.out.println("writeReplace invoked");
  21. return this;
  22. }
  23. private Object readResolve() throws ObjectStreamException {
  24. System.out.println("readResolve invoked");
  25. return this;
  26. }
  27. public Object serialize() throws IOException, ClassNotFoundException {
  28. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  29. ObjectOutputStream oos = new ObjectOutputStream(baos);
  30. oos.writeObject(this);
  31. ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  32. ObjectInputStream ois = new ObjectInputStream(bais);
  33. return ois.readObject();
  34. }
  35. public static void main(String[] args) throws IOException,
  36. ClassNotFoundException {
  37. FooImpl fooimpl = new FooImpl();
  38. fooimpl.serialize();
  39. }

我们运行这段代码看到的debug信息:

writeReplace invoked

writeObject invoked

readObject invoked

readResolve invoked

当进行序列化的时候:

首先JVM会先调用writeReplace方法,在这个阶段,我们可以进行张冠李戴,将需要进行序列化的对象换成我们指定的对象.

跟着JVM将调用writeObject方法,来将对象中的属性一个个进行序列化,我们可以在这个方法中控制住哪些属性需要序列化.

当反序列化的时候:

JVM会调用readObject方法,将我们刚刚在writeObject方法序列化好的属性,反序列化回来.

然后在readResolve方法中,我们也可以指定JVM返回我们特定的对象(不是刚刚序列化回来的对象).

注意到在writeReplace和readResolve,我们可以严格控制singleton的对象,在同一个JVM中完完全全只有唯一的对象,控制不让singleton对象产生副本.

Externalizable 是一个有实际方法需要实现的interface,包括writeExternal和readExternal:

Java代码  

  1. public class FooImpl implements java.io.Externalizable {
  2. private String message;
  3. public String getFoo() {
  4. return message;
  5. }
  6. public void setMessage(String message) {
  7. this.message = message;
  8. }
  9. private Object writeReplace() throws ObjectStreamException {
  10. System.out.println("writeReplace invoked");
  11. return this;
  12. }
  13. private Object readResolve() throws ObjectStreamException {
  14. System.out.println("readResolve invoked");
  15. return this;
  16. }
  17. public Object serialize() throws IOException, ClassNotFoundException {
  18. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  19. ObjectOutputStream oos = new ObjectOutputStream(baos);
  20. oos.writeObject(this);
  21. ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  22. ObjectInputStream ois = new ObjectInputStream(bais);
  23. return ois.readObject();
  24. }
  25. public void readExternal(ObjectInput arg0) throws IOException,
  26. ClassNotFoundException {
  27. System.out.println("readExternal invoked");
  28. Object obj = arg0.readObject();
  29. }
  30. public void writeExternal(ObjectOutput arg0) throws IOException {
  31. System.out.println("writeExternal invoked");
  32. arg0.writeObject("Hello world");
  33. }
  34. public static void main(String[] args) throws IOException,
  35. ClassNotFoundException {
  36. FooImpl fooimpl = new FooImpl();
  37. fooimpl.serialize();
  38. }
  39. }

我们运行这段代码看到的debug信息:

writeReplace invoked

writeExternal invoked

readExternal invoked

readResolve invoked

在此writeExternal 和readExternal 的作用与writeObject和readObject 一样.

最后,当我们同时实现了两个interface的时候,JVM只运行Externalizable 接口里面的writeExternal 和readExternal 方法对序列化内容进行处理.

需要注意的是:Serializable是一个真正的mark interface,

writeObject,readObject, writeReplace,readResolve是直接与JVM通信,告诉JVM序列化的内容.

时间: 2024-11-12 09:13:24

序列化Serializable和Externalizable的区别的相关文章

Java序列化Serializable和Externalizable

纸上得来终觉浅,绝知此事要躬行  --陆游       问渠那得清如许,为有源头活水来  --朱熹 什么是Java序列化?为什么出现Java序列化?如何实现Java序列化? 一.什么是Java序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 二.为什么出现Java序列化 两个进程之间进行通信时,须要传输各种信息.比方文本,图像,声音等等,这些信息是通过二进制流的形式进行传输的. 那么进程之间是不是也能够传递对象数据呢?答案是

序列化---Serializable与Externalizable源码

Serializable接口总结: 1. java.io.Serializable接口是一个标识接口,它没有任何字段和方法,用来表示此类可序列化: 2. 父类声明该接口,则其与其所有子类均可序列化,都无须提供无参构造器(反序列化时不会调用父类或子类的无参构造器) 3. 父类不可序列化,子类声明该接口,父类必须提供子类可访问的无参构造器(子类有无无参构造器均可),程序才能正常运行,但是反序列化后,父类信息均为无参构造器初始化的内容(反序列化时,会调用子类可访问的父类的无参构造器,对父类部分进行初始

java Serializable和Externalizable序列化反序列化详解--转

一.什么是序列化? “对象序列化”(Object Serialization)是 Java1.1就开始有的特性. 简单地说,就是可以将一个对象(标志对象的类型)及其状态转换为字节码,保存起来(可以保存在数据库,内存,文件等),然后可以在适当的时候再将其状态恢复(也就是反序列化).serialization 不但可以在本机做,而且可以经由网络操作.它自动屏蔽了操作系统的差异,字节顺序等.比如,在 Windows 平台生成一个对象并序列化之,然后通过网络传到一台 Unix 机器上,然后可以在这台Un

java io系列06之 序列化总结(Serializable 和 Externalizable)

本章,我们对序列化进行深入的学习和探讨.学习内容,包括序列化的作用.用途.用法,以及对实现序列化的2种方式Serializable和Externalizable的深入研究. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_06.html 1. 序列化是的作用和用途 序列化,就是为了保存对象的状态:而与之对应的反序列化,则可以把保存的对象状态再读出来. 简言之:序列化/反序列化,是Java提供一种专门用于的保存/恢复对象状态的机制. 一般在以下几种

Java序列化(Serializable)与反序列化

序列化是干什么的 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保 存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化. 什么情况下需要序列化 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候: 当你想用套接字在网络上传送对象的时候: 当你想通过RMI传输对象的时候: 序列化的几种方式 在Java中socket传输数据时,数据类型往往比较难

Java 序列化Serializable详解(附详细例子)

Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.   2.什么情况下需要序列化 a)当你想把的内存中的对象保存到一个文件中或者数据库中时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候: 3.如何实现序列化 将需要序列化的类实现Serializable接口就可以了,Seriali

java序列化Serializable那些事

串行化也叫序列化,就是将实例的状态转化成文本(或二近制)的形式,以便永久保存(所以有时候也叫持久化,或者信息的冷藏等等)或在网间传递.也就是说,如果一个类的实例需要持久化或者需要在网间传递的时候,就用到了串行化  Serialization是指把类或者基本的数据类型持久化(persistence)到数据流(Stream)中,包括文件.字节流.网络数据流.         JAVA中实现serialization主要靠两个类:ObjectOuputStream和ObjectInputStream.

Java 序列化Serializable详解(附详细例子)

1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程. 2.什么情况下需要序列化  a)当你想把的内存中的对象保存到一个文件中或者数据库中时候: b)当你想用套接字在网络上传送对象的时候: c)当你想通过RMI传输对象的时候: 3.如何实现序列化 将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明

java 序列化Serializable 详解

Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.   2.什么情况下需要序列化 a)当你想把的内存中的对象保存到一个文件中或者数据库中时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候: 3.如何实现序列化 将需要序列化的类实现Serializable接口就可以了,Seriali