对于这个,有几点我们需要明确:
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机器,然后在那里准确无误地重新“装配”。不必关心数据在不同机器上如何表示,也不必关心字节的顺序或者其他任何细节。