`

Externalizable

    博客分类:
  • J2SE
阅读更多

被Serializable接口声明的类的对象的内容都将被序列化,如果现在用户希望自己指定序列化的内容,则可以让一个类实现Externalizable接口,此接口定义如下:

  1. public interface Externalizable extends Serializable {  
  2.     public void writeExternal(ObjectOutput  out) throws IOException ;  
  3.     public void readExternal(ObjectInput in)  throws IOException,  
  4. ClassNot FoundException ;  

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

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

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

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

ObjectOutput接口定义:

  1. public interface ObjectOutput extends DataOutput 

ObjectInput接口定义:

  1. public interface ObjectInput extends DataInput 

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

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

范例:修改Person类并实现Externalizable接口

  1. package org.lxh.demo12.serdemo;  
  2. import java.io.Externalizable;  
  3. import java.io.IOException;  
  4. import java.io.ObjectInput;  
  5. import java.io.ObjectOutput;  
  6. public class Person implements Externalizable  {// 此类的对象可以被序列化  
  7.     private String name;                       // 声明name属性  
  8.     private int age;                           // 声明age属性  
  9.     public Person(){}                         // 必须定义无参构造  
  10.     public Person(String name, int age) {     // 通过构造方法设置属性内容  
  11.         this.name = name;  
  12.         this.age = age;  
  13.     }  
  14.     public String toString() {                  // 覆写toString()方法  
  15.         return "姓名:" + this.name + ";年龄:" + this.age;  
  16.     }  
  17.     // 覆写此方法,根据需要读取内容,反序列化时使用  
  18.     public void readExternal(ObjectInput in)  throws IOException,  
  19.             ClassNotFoundException {  
  20.         this.name = (String)in.readObject() ;   // 读取姓名属性  
  21.         this.age = in.readInt() ;              // 读取年龄  
  22.     }  
  23.     // 覆写此方法,根据需要可以保存属性或具体内容, 序列化时使用  
  24.     public void writeExternal(ObjectOutput out)  throws IOException {  
  25.         out.writeObject(this.name) ;          // 保存姓名属性  
  26.         out.writeInt(this.age) ;             // 保存年龄属性  
  27.     }  

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

范例:序列化和反序列化Person对象

  1. package org.lxh.demo12.serdemo;  
  2. import java.io.File;  
  3. import java.io.FileInputStream;  
  4. import java.io.FileOutputStream;  
  5. import java.io.InputStream;  
  6. import java.io.ObjectInputStream;  
  7. import java.io.ObjectOutputStream;  
  8. import java.io.OutputStream;  
  9. public class SerDemo03 {  
  10.     public static void main(String[] args)  throws Exception {  
  11.         ser();                               // 序列化  
  12.         dser();                                // 反序列化  
  13.     }  
  14.     public static void ser() throws Exception  {     // 序列化操作  
  15.         File f = new File("D:" + File.separator + "test.txt");  
  16.         ObjectOutputStream oos = null;  
  17.         OutputStream out = new FileOutputStream(f);  // 文件输出流  
  18.         oos = new ObjectOutputStream(out);        // 为对象输出流实例化  
  19.         oos.writeObject(new Person("张三"30));   // 保存对象到文件  
  20.         oos.close();                             // 关闭输出  
  21.     }  
  22.     public static void dser() throws Exception  {        // 反序列化操作  
  23.         File f = new File("D:" + File.separator + "test.txt");  
  24.         ObjectInputStream ois = null;  
  25.         InputStream input = new FileInputStream(f);  // 文件输出流  
  26.         ois = new ObjectInputStream(input);          // 为对象输出流实例化  
  27.         Object obj = ois.readObject();           // 读取对象  
  28.         ois.close();                            // 关闭输出  
  29.         System.out.println(obj);  
  30.     }  

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

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

   

   

Serializable

Externalizable

1

实现复杂度

实现简单,Java对其

有内建支持

实现复杂,

由开发人员自己完成

2

执行效率

所有对象由Java统一保存,

性能较低

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

可能造成速度提升

3

保存信息

保存时占用空间大

部分存储,

可能造成空间减少

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

分享到:
评论

相关推荐

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

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

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

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

    深入探索Java对象的序列化

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

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

    其中,Serializable 接口是 Java 语言提供的默认序列化方式,而 Externalizable 接口则允许开发者自定义序列化行为。 对象流的应用场景很多,如在网络游戏中,需要传输游戏状态、游戏对象等复杂数据;在分布式系统...

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

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

    对象的序列化与反序列化

    - **实现`Externalizable`接口**:如果`Customer`类实现了`Externalizable`接口,那么必须实现`readExternal`和`writeExternal`方法。此时,序列化过程将通过调用`writeExternal`方法进行,而反序列化时,则先通过无...

    java中把对象转化为byte数组的方法.doc

    Java 提供了两种方式来实现序列化:一种是使用 Serializable 接口,另一种是使用 Externalizable 接口。 在上面的代码中,我们可以看到, ByteToObject 方法将 byte 数组转化为对象,而 ObjectToByte 方法将对象...

    java.io.Serializable序列化问题

    使用 `Externalizable` 接口的主要优点在于可以更精确地控制序列化和反序列化过程,这对于需要自定义序列化逻辑的对象非常有用。 #### 六、序列化中的注意事项 - **`transient` 关键字**:使用 `transient` 可以...

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

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

    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

    另外,Java还提供了一个更灵活的序列化接口`Externalizable`,它要求类自己控制序列化和反序列化的过程,需要实现`writeExternal()`和`readExternal()`方法。这种方式更耗费资源,但能更好地控制序列化过程,特别是...

    java对象序列化.ppt

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

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

    2. **实现Externalizable接口**:如果需要更多控制权,可以选择实现`Externalizable`接口,该接口要求实现`writeExternal()`和`readExternal()`方法,从而可以自定义序列化和反序列化的逻辑。 #### 示例代码:序列...

    伤口撕开,给你看.pdf

    实现Externalizable接口的类需要提供两个方法:writeExternal()和readExternal(),用于提供对序列化过程的控制,这比使用Serializable接口时提供的默认序列化行为更加灵活。 知识点二:RMI(Remote Method ...

    j2ee中英文对照版api

    这类命令可以使用 Externalizable 接口或特定于应用程序的方法来获取数据。 英文文档: JavaBeans components that are Activation Framework aware implement this interface to find out which command verb ...

    JAVA对象的序列化与反序列化详细PPT学习教案.pptx

    3. 实现`Externalizable`接口则更为灵活,需要手动实现`writeExternal(ObjectOutput out)`和`readExternal(ObjectInput in)`方法,这允许开发者完全控制对象的序列化和反序列化过程。 序列化和反序列化对于数据的...

Global site tag (gtag.js) - Google Analytics