`

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

    xml的序列化与验证

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

    一线互联网大厂完整Java面试题.pdf

    7. Serializable和Externalizable的区别在于前者是标记接口,通过序列化机制自动保存对象状态,而后者需要实现序列化和反序列化的方法。 8. sleep和wait方法都让线程进入等待状态,但wait方法会释放对象锁,而sleep...

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

    通过这两个类,我们可以看到如何使用 Serializable 和 Externalizable 接口来实现序列化和反序列化。 序列化和反序列化的应用场景非常广泛,例如在分布式系统中,需要将对象的状态信息从一台机器传输到另一台机器上...

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

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

    Java对象序列化操作详解

    * 只有实现了 Serializable 和 Externalizable 接口的类的对象才能被序列化。 代码示例: ```java import java.io.*; public class ObjectSaver { public static void main(String[] args) throws Exception { ...

    java.io.Serializable序列化问题

    ### Java.io.Serializable 序列化...通过实现 `Serializable` 接口或 `Externalizable` 接口,可以轻松地实现序列化和反序列化功能。需要注意的是,在实际应用中还需要考虑序列化的效率、安全性以及版本兼容性等问题。

    LargeCollections

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

    Java对象流在网络编程中的运用.pdf

    在 Java 中,对象流是通过实现 Serializable 或 Externalizable 接口来实现的。其中,Serializable 接口是 Java 语言提供的默认序列化方式,而 Externalizable 接口则允许开发者自定义序列化行为。 对象流的应用...

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

    需要注意的是,只有实现了`Serializable`或`Externalizable`接口的类才能被序列化。`Externalizable`接口允许对象完全控制序列化过程,而仅实现`Serializable`接口的类则采用默认的序列化方式。对于那些不希望被序列...

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

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

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

    2. **实现Externalizable接口**:这个接口继承自`Serializable`,提供了更高级别的控制,允许开发者自己编写序列化逻辑。 3. **序列化兼容性**:`serialVersionUID`的作用在于保证版本兼容性。开发者可以通过显式...

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

    - **`Externalizable`接口**:这是`Serializable`接口的一个子接口,它要求实现类提供两个方法`readExternal`和`writeExternal`来自定义序列化和反序列化的过程。 #### 二、序列化的具体实现方式 在Java中,对象...

    java基础 对象序列化

    `Externalizable`和`Serializable`接口虽然都用于序列化,但它们之间的区别在于控制程度和灵活性。`Serializable`仅是一个标记接口,表明该类可以被序列化;而`Externalizable`则要求类实现`writeExternal()`和`...

    深入探索Java对象的序列化

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

    大学课程讲义-Java基础-IO

    如果需要让某个对象支持序列化机制,则必须让该类实现 Serializable 或 Externalizable 接口。使用对象流序列化对象可以将对象保存到磁盘上或传输到网络中。 ### RandomAccessFile 类 RandomAccessFile 类既可以...

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

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

Global site tag (gtag.js) - Google Analytics