大家都知道Serializable是一个mark interface,告诉JVM这个对象可以被转换成二进制流来传输.
但是Serializable与Externalizable的转换二进制流的过程是不一样的.
Serializable 在我们实现这个接口的时候,我们可以使用4个私有方法来控制序列化的过程:
我们来看一个例子:
public class FooImpl implements java.io.Serializable{
private String message;
public String getFoo() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
System.out.println("writeObject invoked");
out.writeObject(this.message == null ? "hohohahaha" : this.message);
}
private void readObject(java.io.ObjectInputStream in) throws IOException,
ClassNotFoundException {
System.out.println("readObject invoked");
this.message = (String) in.readObject();
System.out.println("got message:" + message);
}
private Object writeReplace() throws ObjectStreamException {
System.out.println("writeReplace invoked");
return this;
}
private Object readResolve() throws ObjectStreamException {
System.out.println("readResolve invoked");
return this;
}
public Object serialize() throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
public static void main(String[] args) throws IOException,
ClassNotFoundException {
FooImpl fooimpl = new FooImpl();
fooimpl.serialize();
}
}
我们运行这段代码看到的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:
public class FooImpl implements java.io.Externalizable {
private String message;
public String getFoo() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
private Object writeReplace() throws ObjectStreamException {
System.out.println("writeReplace invoked");
return this;
}
private Object readResolve() throws ObjectStreamException {
System.out.println("readResolve invoked");
return this;
}
public Object serialize() throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
public void readExternal(ObjectInput arg0) throws IOException,
ClassNotFoundException {
System.out.println("readExternal invoked");
Object obj = arg0.readObject();
}
public void writeExternal(ObjectOutput arg0) throws IOException {
System.out.println("writeExternal invoked");
arg0.writeObject("Hello world");
}
public static void main(String[] args) throws IOException,
ClassNotFoundException {
FooImpl fooimpl = new FooImpl();
fooimpl.serialize();
}
}
我们运行这段代码看到的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序列化的内容.
分享到:
相关推荐
主要介绍了JAVA序列化Serializable及Externalizable区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
NULL 博文链接:https://zhycaf.iteye.com/blog/982092
其中包括以下接口和类: java.io.Serializable java.io.Externalizable ObjectOutput ObjectInput ObjectOutputStream ObjectInputStream Java高级程序设计实战教程第五章-Java序列化机制全文共15页,当前为第7页。...
Java中的序列化机制有两种实现方式: 一种是实现Serializable接口 另一种是实现Externalizable接口 区别: 实现Serializable接口 1 系统自动储存必要的信息 2 Java内建支持,易于实现,只需实现该接口即可,无须任何...
Serializable接口和Externalizable接口实现序列化和反序列化
Serializable有一个子接口Externalizable,实现Externalizable接口的类可以自行控制对象序列化荷反序列化过程。 一般来说,没有必要自己实现序列化接口,直接交给Java虚拟机是上策。 实现了序列化接口的类,如果...
1、xml序列化的Java3种实现方法 1)Serializable和Externalizable接口Xstream框架2)Simple框架 3)Apache的AXIOM框架 2、XML验证文档的生成工具 trang.jar 3、利用XSD文件的XML3种验证方法 1)Dom4j的SAXValidator ...
最近阅读Serializable接口和Externalizable接口的源码,并结合了一些资料,对面试过程中与序列化相关的内容做了一些总结。 一、序列化、反序列化、使用场景、意义。 序列化:将对象写入IO流中; 反序列化:从IO流中...
Groovy-io 往返于JSON格式的完美序列化(可在)。 要包含在您的项目中: ... <artifactId>groovy-io <version>1.1.3 groovy-io由两个主要类组成,一个... groovy-io不需要类实现Serializable或Externalizable来进
Serializable 类通过实现 java.io.Serializable 接口以启用其序列化功能。 类摘要 BufferedInputStream BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。 ...