`

比较java.io.Externalizable和java.io.Serializable

阅读更多
http://soft.zdnet.com.cn/software_zone/2009/0204/1332403.shtml
即使你没有用过对象序列化(serialization),你可能也知道它。但你是否知道 Java 还支持另外一种形式的对象持久化,外部化(externalization)?

下面是序列化和外部化在代码级的关联方式:

public interface Serializable {}

public interface Externalizable extends Serializable {
  void readExternal(ObjectInput in);
  void writeExternal(ObjectOutput out);
}

序列化和外部化的主要区别

外部化和序列化是实现同一目标的两种不同方法。下面让我们分析一下序列化和外部化之间的主要区别。

通过Serializable接口对对象序列化的支持是内建于核心 API 的,但是java.io.Externalizable的所有实现者必须提供读取和写出的实现。Java 已经具有了对序列化的内建支持,也就是说只要制作自己的类java.io.Serializable,Java 就会试图存储和重组你的对象。如果使用外部化,你就可以选择完全由自己完成读取和写出的工作,Java 对外部化所提供的唯一支持是接口:

voidreadExternal(ObjectInput in)
void writeExternal(ObjectOutput out)

现在如何实现readExternal() 和writeExternal() 就完全看你自己了。

序列化会自动存储必要的信息,用以反序列化被存储的实例,而外部化则只保存被存储的类的标识。当你通过java.io.Serializable接口序列化一个对象时,有关类的信息,比如它的属性和这些属性的类型,都与实例数据一起被存储起来。在选择走Externalizable这条路时,Java 只存储有关每个被存储类型的非常少的信息。

每个接口的优点和缺点

Serializable接口

·         优点:内建支持

·         优点:易于实现

·         缺点:占用空间过大

·         缺点:由于额外的开销导致速度变比较慢

Externalizable接口

·         优点:开销较少(程序员决定存储什么)

·         优点:可能的速度提升

·         缺点:虚拟机不提供任何帮助,也就是说所有的工作都落到了开发人员的肩上。

在两者之间如何选择要根据应用程序的需求来定。Serializable通常是最简单的解决方案,但是它可能会导致出现不可接受的性能问题或空间问题;在出现这些问题的情况下,Externalizable可能是一条可行之路。

要记住一点,如果一个类是可外部化的(Externalizable),那么Externalizable方法将被用于序列化类的实例,即使这个类型提供了Serializable方法:

private void writeObject()
private void readObject()
下面是Externalizable的一个example
import java.io.Externalizable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class AppTest {
	private void saveGame(){
		Person m = new Person("北京","cdq",34);
		if (m != null){
			try{
				FileOutputStream ostream = new FileOutputStream(System.getProperty("user.dir")+"/t.txt");
				ObjectOutputStream p = new ObjectOutputStream(ostream);

				p.writeObject(m); //writeExternal()自动执行

				p.flush();
				ostream.close();
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}
		}
	}

	private void loadGame(){
		try{
			FileInputStream instream = new FileInputStream("t.txt");
			ObjectInputStream p = new ObjectInputStream(instream);
			Person m = (Person)p.readObject();//readExternal()自动执行

			m.output();
			instream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		new AppTest().saveGame();
		new AppTest().loadGame();

	}


}

class Person implements Externalizable
{
	private String address;
	private String name;

	private int num;
	
	public Person()
	{
		
	}
	public Person(String address,String name,int num)
	{
		this.address = address;
		this.name=name;
		this.num=num;
	}
	public void readExternal(ObjectInput in) throws IOException,
	ClassNotFoundException {
		address = (String)in.readObject();
		num = in.read();
		//name = (String)in.readObject();没有写入就不能读取不然会抛出OptionalDataException异常
	}

	public void writeExternal(ObjectOutput out) throws IOException {

		out.writeObject(address);
		//只序列化address
		out.write(88);
	}	

	public void output()
	{
		System.out.println("address="+address+",num="+num+",name="+name);
	}

}
分享到:
评论

相关推荐

    java.io.Serializable序列化问题

    ### Java.io.Serializable 序列化问题详解 #### 一、序列化的概念与作用 在 Java 编程语言中,序列化是一种将对象的状态(即成员变量的值)转换为可以存储或传输的形式的过程。通常,这种形式是字节流,但也可以是...

    java jdk io包类详解

    通过对`java.io`包中的类和接口的学习,我们不仅能够深入了解Java中基础输入输出流的实现原理,还能够掌握如何高效地处理文件和其他数据流。这对于日常的软件开发工作是非常有用的。此外,通过理解装饰者模式的应用...

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

    Java 串行化主要通过实现`java.io.Serializable`接口来实现,同时也提供了`java.io.Externalizable`接口来提供更细粒度的控制。 **一、Serializable接口** `Serializable`是Java中的一个标记接口,没有包含任何方法...

    java中的序列号和反序列化.doc

    此外,还有更高级的序列化方式,即实现`java.io.Externalizable`接口。这种方式完全由程序员控制序列化过程,`writeExternal`和`readExternal`方法分别用于序列化和反序列化。这种方式提供了更大的灵活性,但需要...

    Java存储与读取对象源码

    此外,Java提供了`Externalizable`接口作为`Serializable`的替代,允许自定义序列化和反序列化的行为,但这需要程序员手动编写更多的代码。 另外,如果你的类中包含不希望序列化的字段,可以使用`transient`关键字...

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

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

    Java标准类库(java基础类)

    ### Java标准类库(java基础类) #### 概述 Java标准类库是Java编程...总之,`java.io`包是Java开发者处理文件和I/O操作的重要工具箱,深入理解和熟练掌握其提供的API对于提高Java应用程序的性能和可靠性至关重要。

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

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

    Java IO 性能优化

    1. **使用自定义序列化逻辑**:通过实现`Serializable`接口的子接口`Externalizable`,可以控制对象的序列化和反序列化过程。这样可以在序列化过程中省略不必要的字段或者采用更高效的编码方式。 2. **选择合适的...

    JAVA_IO操作总结——节点流和处理流.pdf

    ### JAVA IO操作总结——节点流和处理流 #### 一、概述 在Java中,输入/输出(Input/Output,简称IO)操作是一项非常重要的功能,它涉及到如何从不同的源读取数据以及如何向不同的目的地写入数据。Java IO体系主要...

    通过实例了解java序列化机制

    要实现序列化的类必须实现的java.io.Serializable或java.io.Externalizable接口,否则将产生一个NotSerializableException。该接口内部并没有任何方法,它只是一个"tagging interface",仅仅"tags"它自己的对象是一...

    JAVA_IO

    在Java的版本1.2中,JAVA_IO模块进行了显著的改进,增强了数据流类的方法,使得如`close()`、`read()`、`ready()`和`write()`等方法更符合其语义,同时`PrintStream`和`PrintWriter`的内部实现也得到了优化,提高了...

    java对象序列化.ppt

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

    北大Java--IO

    - Java的I/O主要由`java.io`包中的类和接口实现,标准输入/输出处理由`java.lang`包中的类支持,但这些类都继承自`java.io`。 - 在JDK1.1之前,I/O流主要处理字节流,但JDK1.1之后引入了字符流(基于`Reader`和`...

    java序列化和反序列化1

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

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

    `java.io.ObjectOutputStream`和`java.io.ObjectInputStream`是Java标准库中用于序列化和反序列化的类。前者通过`writeObject()`方法将对象写入输出流,后者通过`readObject()`方法从输入流中读取对象。 需要注意的...

    Java对象序列化

    - **序列化工具类**:Java提供了`java.io.ObjectOutputStream`和`java.io.ObjectInputStream`两个类来进行对象的序列化和反序列化操作。 ##### ObjectOutputStream - **构造函数**:需要传入一个`OutputStream`...

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

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

    详解Java 序列化与反序列化(Serialization)

    在 Java 中,有两个接口可以实现序列化:Serializable 和 Externalizable。其中,Serializable 是一个标记接口,实现了这个接口的类可以被序列化,但需要重写 writeObject 和 readObject 方法。如果没有重写这些方法...

Global site tag (gtag.js) - Google Analytics