`

Serializable和Externalizable

 
阅读更多

 

 *
 * @author  unascribed
 * @see java.io.ObjectOutputStream
 * @see java.io.ObjectInputStream
 * @see java.io.ObjectOutput
 * @see java.io.ObjectInput
 * @see java.io.Serializable
 * @since   JDK1.1
 */
public interface Externalizable extends java.io.Serializable {
    /**
     * The object implements the writeExternal method to save its contents
     * by calling the methods of DataOutput for its primitive values or
     * calling the writeObject method of ObjectOutput for objects, strings,
     * and arrays.
     *
     * @serialData Overriding methods should use this tag to describe
     *             the data layout of this Externalizable object.
     *             List the sequence of element types and, if possible,
     *             relate the element to a public/protected field and/or
     *             method of this Externalizable class.
     *
     * @param out the stream to write the object to
     * @exception IOException Includes any I/O exceptions that may occur
     */
    void writeExternal(ObjectOutput out) throws IOException;

    /**
     * The object implements the readExternal method to restore its
     * contents by calling the methods of DataInput for primitive
     * types and readObject for objects, strings and arrays.  The
     * readExternal method must read the values in the same sequence
     * and with the same types as were written by writeExternal.
     *
     * @param in the stream to read data from in order to restore the object
     * @exception IOException if I/O errors occur
     * @exception ClassNotFoundException If the class for an object being
     *              restored cannot be found.
     */
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

 

 

Externalizable接口是Serializable接口的子接口,在此接口中定义了两个方法,这两个方法的作用如下。

writeExternal(ObjectOutput out):在此方法中指定要保存的属性信息,对象序列化时调用。

readExternal(ObjectInput in):在此方法中读取被保存的信息,对象反序列化时调用。

这两个方法的参数类型是ObjectOutput和ObjectInput,两个接口的定义如下。

ObjectOutput接口定义:

public interface ObjectOutput extends DataOutput 

ObjectInput接口定义:

public interface ObjectInput extends DataInput 

可以发现以上两个接口分别继承DataOutput和DataInput,这样在这两个方法中就可以像DataOutputStream和DataInputStream那样直接输出和读取各种类型的数据。

如果一个类要使用Externalizable实现序列化时,在此类中必须存在一个无参构造方法,因为在反序列化时会默认调用无参构造实例化对象,如果没有此无参构造,则运行时将会出现异常,这一点的实现机制与Serializable接口是不同的。

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;


public class Person implements Externalizable {

	private String name;
	private int age;



	public Person() {
	}



	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String toString() {                  // 覆写toString()方法  
		return "姓名:" + this.name + ";年龄:" + this.age;  
	} 



	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	// 覆写此方法,根据需要可以保存属性或具体内容, 序列化时使用  
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(this.name) ;          // 保存姓名属性  
		out.writeInt(this.age) ;             // 保存年龄属性
	}

	//// 覆写此方法,根据需要读取内容,反序列化时使用 
	@Override
	public void readExternal(ObjectInput in) throws IOException,
	ClassNotFoundException {
		this.name = (String)in.readObject() ;   // 读取姓名属性  
		this.age = in.readInt() ;   

	}

}

 

 

以上程序中的Person类实现了Externalizable接口,这样用户就可以在类中有选择地保存需要的属性或者其他的具体数据。在本程序中,为了与之前的程序统一,将全部属性保存下来。

 

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;


public class SerDemo03 {  
    public static void main(String[] args)  throws Exception {  
        ser();                               // 序列化  
        dser();                                // 反序列化  
    }  
    public static void ser() throws Exception  {     // 序列化操作  
        File f = new File("D:" + File.separator + "test.txt");  
        ObjectOutputStream oos = null;  
        OutputStream out = new FileOutputStream(f);  // 文件输出流  
        oos = new ObjectOutputStream(out);        // 为对象输出流实例化  
        oos.writeObject(new Person("张三", 30));   // 保存对象到文件  
        oos.close();                             // 关闭输出  
    }  
    public static void dser() throws Exception  {        // 反序列化操作  
        File f = new File("D:" + File.separator + "test.txt");  
        ObjectInputStream ois = null;  
        InputStream input = new FileInputStream(f);  // 文件输出流  
        ois = new ObjectInputStream(input);          // 为对象输出流实例化  
        Object obj = ois.readObject();           // 读取对象  
        ois.close();                            // 关闭输出  
        System.out.println(obj);  
    }  
} 

 从以上代码中可以发现,使用Externalizable接口实现序列化明显要比使用Serializable接口实现序列化麻烦得多,除此之外,两者的实现还有不同,如表12-27所示。

表12-27  Externalizable接口与Serializable接口实现序列化的区别

    

    

Serializable

Externalizable

1

实现复杂度

实现简单,Java对其

有内建支持

实现复杂,

由开发人员自己完成

2

执行效率

所有对象由Java统一保存,

性能较低

开发人员决定哪个对象保存,

可能造成速度提升

3

保存信息

保存时占用空间大

部分存储,

可能造成空间减少

在一般的开发中,因为Serializable接口的使用较为方便,所以出现较多

 

 

相比Serializable,Externalizable序列化的速度更快,序列化之后的数据更小,但读和取都需要开发人员自行实现; 

Serializable开发相对简单,速度慢,序列化后的数据更大些。 

 

 

这两种序列化方式都有一个特点,如果多个对象a的内部属性b同时指向同一个对象,即同时引用了另外一个对象b。序列化->反序列化之后,这几个对象属性还是会同时指向同一个对象b,不会反序列化出多个b对象。 

但是,如果多个对象a是多次被序列化的,在反序列后对象b会被反序列化多次,即多个a对象的属性b是不一样的。 

 

Serializable是整个对象的序列化,不管需不需要,这个过程不需要我们来设计实现。

Externalizable是对对象有选择的进行序列化,根据业务的需要对相应的属性实现序列化,并且这个过程需要我们自己来实现。

感觉有点像hibernate与ibatis...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    JAVA序列化Serializable及Externalizable区别详解

    主要介绍了JAVA序列化Serializable及Externalizable区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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

    NULL 博文链接:https://zhycaf.iteye.com/blog/982092

    xml的序列化与验证

    1)Serializable和Externalizable接口Xstream框架2)Simple框架 3)Apache的AXIOM框架 2、XML验证文档的生成工具 trang.jar 3、利用XSD文件的XML3种验证方法 1)Dom4j的SAXValidator (dom4j.jar, javax.xml....

    VALJOGen:VALue Java 对象生成器 (VALJOGen)

    支持Serializable和Externalizable接口的自动实现。 极其可定制的代码输出。 您可以更改生成的类的每个方面,甚至可以使用基于的自定义模板添加您自己的代码。 对不可变值对象的强大支持,包括最终字段和不可变...

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

    Serializable接口和Externalizable接口实现序列化和反序列化

    LargeCollections

    虽然 LargeCollections 支持任何 Serializable/Externalizable/Writable/Kryo-Serializable Key 和 Value 类,但底层实现将所有内容存储为字节数组键值存储(类似于 HBase)。 因此,每个键/值实例都需要转换为

    groovy-io:与JSON格式之间完美的Groovy序列化。 此外,还支持JSON的精美打印(与jsonEditorOnline样式匹配)

    Groovy-io 往返于JSON格式的完美序列化(可在)。 要包含在您的项目中: ... <artifactId>groovy-io <version>1.1.3 groovy-io由两个主要类组成,一个... groovy-io不需要类实现Serializable或Externalizable来进

    深入探索Java对象的序列化

    Serializable有一个子接口Externalizable,实现Externalizable接口的类可以自行控制对象序列化荷反序列化过程。 一般来说,没有必要自己实现序列化接口,直接交给Java虚拟机是上策。 实现了序列化接口的类,如果...

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

    一种是实现Serializable接口 另一种是实现Externalizable接口 区别: 实现Serializable接口 1 系统自动储存必要的信息 2 Java内建支持,易于实现,只需实现该接口即可,无须任何代码支持 3 性能略差 实现...

    java序列化和反序列化,面试必备

    最近阅读Serializable接口和Externalizable接口的源码,并结合了一些资料,对面试过程中与序列化相关的内容做了一些总结。 一、序列化、反序列化、使用场景、意义。 序列化:将对象写入IO流中; 反序列化:从IO流中...

    JDK_API_1_6

    Externalizable Externalizable 实例类的唯一特性是可以被写入序列化流中,该类负责保存和恢复实例内容。 FileFilter 用于抽象路径名的过滤器。 FilenameFilter 实现此接口的类实例可用于过滤器文件名。 ...

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

    其中包括以下接口和类: java.io.Serializable java.io.Externalizable ObjectOutput ObjectInput ObjectOutputStream ObjectInputStream Java高级程序设计实战教程第五章-Java序列化机制全文共15页,当前为第7页。...

Global site tag (gtag.js) - Google Analytics