现在的位置: 首页 > 综合 > 正文

Java Serializable

2018年04月22日 ⁄ 综合 ⁄ 共 2316字 ⁄ 字号 评论关闭

  java.io.Serializable接口内部没有实现任何东西,这个接口是一个制造者(marker)接口。也就是说,对于要实现它的类来说,该接口不需要实现任何方法。它主要用来通知Java虚拟机(JVM),需要将一个对象序列化。

对于这个,有几点我们需要明确:
1.并非所有类都可以序列化,在cmd下,我们输入serialver java.net.socket,可以得到socket是否可序列化的信息,实际上socket是不可序列化的。
2.java有很多基础类已经实现了serializable接口,比如string,vector等。但是比如hashtable就没有实现serializable接口。     将对象读出或者写入流的主要类有两个: ObjectOutputStream与ObjectInputStream 。ObjectOutputStream 提供用来将对象写入输出流的writeObject方法, ObjectInputStream提供从输入流中读出对象的readObject方法。使用这些方法的对象必须已经被序列化的。也就是说,必须已经实现
Serializable接口。如果你想writeobject一个hashtable对象,那么,会得到一个异常。

下面举个例子:

import java.io.*;

public class testser implements Serializable {
       public int ii;

       testser() {

       }

       testser(int param) {
              ii = param;
       }

}
//上面这个类实现了Serializable ,内部维护一个属性ii。

//下面这个类来调用,将testser 类的对象进行读写操作,并存入文件中。

import java.io.*;

public class Ser {

 private static String datafile = "ser.data";

        public static void main(String[] argv) {
                System.out.println("Java Serialization Demo.");
                testser data;
                try {
                        ObjectInputStream in = new ObjectInputStream(new FileInputStream(
                          datafile));
                        data = (testser) in.readObject();
                        in.close();
                 } catch (Exception e) {
                        data = new testser();
                 }
                System.out.println("Original data: ii = " + data.ii);
                data.ii++;
                try {
                         ObjectOutputStream out = new ObjectOutputStream(
                               new FileOutputStream(datafile));
                         out.writeObject(data);
                         out.flush();
                         out.close();
               } catch (Exception e) {
                        System.out.println(e);
               }
        }
}
若testser 类未实现Serializable 接口,则在这句代码抛出异常 out.writeObject(data);

虽然这个序列化接口没有任何方法和域,但会为每个类生成一个序列号,生成依据是类名、类实现的接口名、public和protected方法,所以只要你一不小心改了一个已经publish的API,并且没有自己定义一个long类型的叫做serialVersionUID的field,哪怕只是添加一个getXX,就会让你读原来的序列化到文件中的东西读不出来。

比如说在testser 类中加入

 public int getIi() {
      return ii;
 }

 public void setIi(int ii) {
      this.ii = ii;
 }

则刚刚写入文件的对象就无法读取处理。

        到底为什么要序列化呢?“对象序列化”(Object  Serialization)。它面向那些实现了Serializable接口的对象,可将它们转换成一系列字节,并可在以后完全恢复回原来的样子。这一过程亦可通过网络进行。这意味着序列化机制能自动补偿操作系统间的差异。换句话说,可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误地重新“装配”。不必关心数据在不同机器上如何表示,也不必关心字节的顺序或者其他任何细节。

抱歉!评论已关闭.