Java 对象序列化
对象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象。对象序列化机制允许把内存中的 java 对象转换成为与平台无关的二进制流,从而允许把这种二进制流持久保存到磁盘上。
实现对象序列化:该类实现接口 serialize 和 externlizable 即可 。
(1) 创建一个 ObjectOutputStream 对象 ;
(2) 调用 ObjectOutputStream 对象的 writeObject 方法;
public class TestSerial implements Serializable{
public byte version = 100;
public byte count = 0;
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileOutputStream fos = new FileOutputStream( "temp.out" );
ObjectOutputStream oos = new ObjectOutputStream(fos);
TestSerial ts = new TestSerial();
oos.writeObject(ts);
oos.flush();
oos.close();
}
}
如果希望从二进制流中恢复 java 对象,则需要使用反序列化。
(1) 创建一个 ObjectInputStream 对象;
(2) 调用该对象的 readObject 方法。
在反序列化的时候,无须通过构造器来初始化 Java 对象;
如果向文件中使用序列化机制写入了多个 java 对象,使用反序列化机制恢复对象的时候,必须按实际写入顺序读取。
Java 对象的序列化机制算法:
(1) 所有保存到磁盘的对象都有一个序列化编号;
(2) 当程序视图序列化一个对象时,程序将首先检查该对象是否已经被序列化过,只有当该对象从未序列化过,系统才会将对象转化成为走空额序列输出;
(3) 如果对象已经序列化过,程序将直接输出一个序列化编号;
递归序列化 :
当对某个对象进行序列化的时候,系统会自动把该对象的所有属性依次序列化,如果某个属性引用了另外一个对象,则被引用的对象也会被序列化,这样依次下去。
自定义序列化有如下几种实现方式:
(1) 通过 transient 关键字修饰属性,该属性在就不会被序列化。
(2) 在该对象中重写 writeObject 方法和 readObject 方法。通过重写 writeObject 方法,程序员可以完全获得对序列化的控制。(调用 writeObject 方法、 writeInt 方法等等,相应地, readObject 调用 readObject 和 readInt 方法就可以了)。
(3) writeReplace 方法。这是一种更为彻底的自定义机制,它甚至可以在序列化对象的时候,将该对象替换为其它对象。 Java 的序列化机制保证在序列化某个对象之前,先调用该对象的 writeObject 方法,如果该方法返回另外一个 Java 对象,则系统转为序列化另一个对象。
(4) Java 类实现 Externalizable 接口。 Externalizable 接口定义了两个方法: void readExternal(ObjectInput in): 用来实现反序列化; void writeExternal(ObjectOutput out) 。这个方法的实现,与重写 writeObject 和 readObject 方法的方法体是一模一样的。
两种序列化机制的对比表如下:
实现 serializable 接口 |
实现 Externalizable 接口 |
系统自动存储必要信息 |
程序员决定存储哪些信息 |
Java 内建支持,易于实现 |
仅仅提供两空方法。 |
性能略差 |
性能略高 |
关于对象的序列化,还要注意一下几点:
1 . 对象的类名、属性(包括基本属性、数组、对其他对象的引用)都会被序列化;方法、 static 属性、 transient 属性都不会被序列化;
2. 保证序列化对象的属性的类型也是可以序列化的;
3. 反序列化的时候,必须要有序列化对象的 class 文件
4. 当通过文件、网络来读取序列化对象后,必须按照实际写入的顺序读取;