java.io.serializable 2

java.io.serializable - [技术探讨]

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://lvdairy.blogbus.com/logs/25344996.html

 

对象序列化概述
对象序列化机制对于需要将对象的状态保存到文件中,而后能够通过读入对象状态来重新构造对象,恢复程序状态,或者使用套接字在网络上传送对象的程序来说,是很有用的。通过让类实现java.io.Serializable 接口可以将类序列化。这个接口是一个制造者(marker)接口。也就是说,对于要实现它的类来说,该接口不需要实现任何方法。它主要用来通知Java虚拟机(JVM),需要将一个对象序列化。

将对象读出或者写入流的主要类有两个: ObjectOutputStream与ObjectInputStream 。ObjectOutputStream 提供用来将对象写入输出流的writeObject方法, ObjectInputStream提供从输入流中读出对象的readObject方法。注意使用这些方法的对象必须被序列化,这非常重要。也就是说,这些类必须实现Serializable接口。

序列化已经存在的类
了解了对象序列化的基础知识之后,我们来看看如何对流读/写对象或现有的已序列化类实例。要将一个对象写入输出流,先建立一个输出流,然后使用writeObject对象保存到文件中。


--------------------------------------------------------------------------------
注意: Date类是可序列化的。换句话说,它实现 Serializable接口。
--------------------------------------------------------------------------------

例程 1: SaveDate.java

import java.io.*;
import java.util.Date;

public class SaveDate {

  public static void main(String argv[]) throws Exception {
    FileOutputStream fos = new FileOutputStream("date.out");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    Date date = new Date();
    oos.writeObject(date);
    oos.flush();
    oos.close();
    fos.close();
  }
}

读入对象,然后重新构造它的状态都很容易。例程2中的代码向您展示了如何读一个已经序列化的对象并且打印它的信息。


例程 2: ReadDate.java

import java.io.*;
import java.util.Date;

public class ReadDate {

  public static void main(String argv[]) throws Exception {
    FileInputStream fis = new FileInputStream("date.out");
    ObjectInputStream ois = new ObjectInputStream(fis);
    Date date = (Date) ois.readObject();
    System.out.println("The date is: "+date);
    ois.close();
    fis.close();
  }
}

在上面的例子中我们使用了Date类的一个实例,这是一个现成的已序列化的Java类。也许您会问这样的问题:是不是所有现成的Java类都是可序列化的?答案是否定的。这不仅因为这样做没必要,而且将某些类序列化是毫无意义的。使用JDK中的serialver工具,可以判断一个类是不是可序列化的。您可以在命令行模式下使用如下命令:

c:> serialver java.util.Date
java.util.Date: static final long serialVersionUID = 7523967970034938905L;

(这个例子测试Date类是不是可序列化。输出结果表示Date类是可序列化的,并且打印出了这个类的版本唯一标识符。)

或者,您也可以使用如下命令启动图形界面下的serialver工具:

c:> serialver -show

 

 

这个命令将弹出一个如图1所示的窗口,在这个窗口中写入您想检查的类的名字(包括路径)。图1显示的结果表示 Date类是可序列化的。

 

再说一次,不是所有的Java类都是可序列化的。举个例子,图2表明Socket类是不可序列化的。


序列化用户自己的类
现在,让我们看看如何序列化用户自己写的类。在这个例子中,我们将建立一个用户类UserInfo,见例程3。为了让它可序列化,UserInfo类实现了Serializable接口。

例程 3: UserInfo.java

import java.io.*;
import java.util.*;

public class UserInfo implements Serializable {
   String name = null;

   public UserInfo(String name) {
      this.name = name;
   }

   public void printInfo() {
      System.out.println("The name is: "+name);
   }
}

下一步就是建立一个能创建UserInfo类实例的类,然后将对象写入输出流中,如例程4。本例中的输出流是一个名为"name.out"的文件。要注意的是,例程4 中的writeObject方法可以被调用任意多次,将任意多个对象写入输出流。

例程 4: SaveInfo.java

import java.io.*;
import java.util.Date;

public class SaveInfo {

  public static void main(String argv[]) throws Exception {
    FileOutputStream fos = new FileOutputStream("name.out");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    // create two objects
    UserInfo user1 = new UserInfo("Java Duke");
    UserInfo user2 = new UserInfo("Java Blue");
    // write the objects to the output stream
    oos.writeObject(user1);
    oos.writeObject(user2);
    oos.flush();
    oos.close();
    fos.close();
  }
}

最后,我们写一个将已经保存的对象读入的类,并且调用一个如例程5所示的方法。和writeObject 一样,readObject方法能被调用任意多次,从输入流中读入任意多个对象。

例程 5: ReadInfo.java

import java.io.*;
import java.util.Date;

public class ReadInfo {

  public static void main(String argv[]) throws Exception {
    FileInputStream fis = new FileInputStream("name.out");
    ObjectInputStream ois = new ObjectInputStream(fis);
    // read the objects from the input stream (the file name.out)
    UserInfo user1 = (UserInfo) ois.readObject();
    UserInfo user2 = (UserInfo) ois.readObject();
    // invoke a method on the constructed object
    user1.printInfo();
    user2.printInfo();
    ois.close();
    fis.close();
  }
}

要测试这个例子,请编译如下源文件:UserInfo.java, SaveInfo.java, 和 ReadInfo.java。运行 SaveInfo,然后运行ReadInfo,将看到类似下面的输出结果:

The name is: Java Duke
The name is: Java Blue

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章