`
dovecat
  • 浏览: 39723 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JAVA序列化基础知识Serializable与Externalizable的区别

    博客分类:
  • java
阅读更多
大家都知道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序列化的内容.
分享到:
评论
1 楼 shuaiji 2012-06-13  
有点看不懂呢

相关推荐

    Java 串行化(序列化)Serializable/Externalizable

    在 serializable-prj 项目中,可能包含了各种示例代码,展示了如何在Java中实现和使用序列化功能。 综上所述,Java的序列化和外部化是实现对象持久化和跨进程通信的关键技术。理解并熟练掌握这些概念,能够帮助...

    java序列化和反序列化的方法

    在 Java 中,序列化和反序列化是通过实现 Serializable 接口来实现的。Serializable 接口是一个标记接口,不包含任何方法,但它告诉 Java虚拟机(JVM)该类可以被序列化。 在上面的代码中,我们可以看到 ...

    Java序列化(Serializable)与反序列化__1.docx

    Java序列化(Serializable)是Java平台提供的一种持久化机制,允许将对象的状态转换为字节流,以便存储到磁盘、数据库中,或者在网络上传输。这一过程被称为对象的序列化。反之,将字节流恢复为原来的对象状态称为反...

    Java序列化(Serializable)与反序列化_.docx

    ### Java序列化(Serializable)与反序列化详解 #### 序列化概念与应用场景 序列化是指将程序中的对象转换为一系列字节序列的过程,主要用于保存对象的状态以便将来使用或者在网络之间传输对象。Java提供了内置的...

    java.io.Serializable序列化问题

    除了 `Serializable` 接口之外,Java 还提供了 `Externalizable` 接口来控制序列化过程。`Externalizable` 继承自 `Serializable`,并定义了两个方法: 1. `void writeExternal(ObjectOutput out)`:用来指定对象...

    java对象序列化.ppt

    要实现对象序列化,Java类必须实现`Serializable`接口或`Externalizable`接口。`Serializable`接口是一个空接口,当一个类实现它时,表明该类的所有实例都可以被序列化。而`Externalizable`接口提供了更多的控制权,...

    Java对象序列化标准最新版

    ### Java对象序列化标准知识点详解 #### 一、系统架构概览 **1.1 概览** Java 对象序列化是一种将Java对象的状态转换成字节流的过程,以便于在网络上传输或存储到磁盘上。Java序列化标准定义了一套规则来描述如何...

    Java实现序列化例子

    在Java中,如果一个类需要支持序列化,那么这个类就需要实现`java.io.Serializable`接口,尽管该接口没有任何方法需要实现,但它的存在就标志着这个类的对象可以被序列化。 首先,我们来看一下`SerializableDemo`这...

    java序列化与反序列化

    Java序列化是将Java对象转换为字节流的过程,以便可以在磁盘、数据库或网络上存储或传输这些对象。这使得我们能够保存对象的状态,并在稍后的时间点恢复它,或者在网络之间传递对象。反序列化是相反的过程,即从字节...

    Java 文件 序列化 读写

    在Java中,`java.io.Serializable`接口用于标记那些可以被序列化的类。下面将详细介绍Java文件序列化读写的相关知识点。 1. **序列化的目的**: - **持久化对象**:将对象状态保存到文件或数据库中,即使程序关闭...

    Java中的序列化与反序列化.pdf

    总结来说,Java中的序列化和反序列化是通过`Serializable`接口和`Externalizable`接口来实现的。`Serializable`接口是默认的序列化方式,适用于大多数简单情况;而`Externalizable`接口则提供了自定义序列化行为的...

    探索Java序列化与反序列化的奥秘:数据持久化的桥梁

    ### Java序列化与反序列化的深入解析 #### Java序列化的重要性及应用场景 Java序列化是一项核心功能,它允许程序员将对象的状态转化为字节流的形式,从而实现对象的持久化存储或者在网络之间进行传递。这对于诸如...

    java序列化和反序列化1

    - **Externalizable**:继承自Serializable接口,提供更细粒度的控制,允许开发者自定义序列化和反序列化的行为。 4. **序列化和反序列化步骤** - **序列化**: - 创建`ObjectOutputStream`,可以传入一个其他...

    java序列化方式Java系列2021.pdf

    Java序列化主要有两种方式:隐式序列化(实现Serializable接口)和显式序列化(实现Externalizable接口)。 ### 隐式序列化 **实现Serializable接口**:这是最常见也是最简单的一种序列化方式。只要一个类实现了`...

    JAVA对象的序列化与反序列化详细PPT课件.pptx

    另外,还有`java.io.Externalizable`接口,它继承自`Serializable`,但提供了更细粒度的控制权,允许类自定义序列化和反序列化的行为。如果一个类实现了`Externalizable`,则需要手动实现`writeExternal...

    Java 对象序列化详解以及实例实现和源码下载

    Java中的序列化机制有两种实现方式: 一种是实现Serializable接口 另一种是实现Externalizable接口 区别: 实现Serializable接口 1 系统自动储存必要的信息 2 Java内建支持,易于实现,只需实现该接口即可,无须任何...

    Java高级程序设计实战教程第五章-Java序列化机制.pptx

    `Serializable`接口是标识对象是否可序列化的标志,`Externalizable`接口允许更精细的控制序列化过程。 5.3 实施过程: 5.3.1 序列化:通过实现`Serializable`接口,然后使用`ObjectOutputStream`的`writeObject()`...

    java序列化对象的存储和读取共6页.pdf.zip

    在Java中,要实现一个对象的序列化,该类必须实现`java.io.Serializable`接口,这是一个标记接口,不包含任何方法。 1. **什么是序列化:** 序列化是将对象转换为字节序列的过程,这个字节序列可以被保存到磁盘、...

Global site tag (gtag.js) - Google Analytics