序列化和反序列化是通過ObjectInputStream和ObjectOutputStream的readObject()和writeObject()實現的,序列化的過程是一個對象流狀態保存的過程,這裡什麼叫對象流,可以理解為一系列的對象,因為本身一個對象的內部的字段都是一個個對象,實際上是通過“級聯”的方式,保存跟此對象所有關聯的對象的狀態,實際上保存了跟此對象有關系的一張“對象網”。
反序列化是還原對象狀態的過程,這種還原的過程可能在同一個應用中,可能在不同的應用中,可能在不同的主機上,還原的過程不是讀出原來對象的字段值然後調用構造函數重新new一個對象,而是“直接地”反序列化為一個Object對象,並沒有調用該類的構造函數,jvm也沒有加載該類到方法區,還原後的對象若在不同的主機,想通過反射獲得更多改對象的描述信息,必須保證JVM能在本地類路徑或者因特網的其他什麼地方找到相關的.class文件。
序列化也可以自己控制,使用Externalizable接口,此接口繼承自Serializable接口,和Serializable不同的是,使用Externalizable接口,在恢復對象的時候是調用的該類的無參構造方法,若無參構造方法不是public的,在恢復對象的時候會拋出異常,下面的代碼節選自Think in java
- package externalizable;
-
- import java.io.Externalizable;
- import java.io.IOException;
- import java.io.ObjectInput;
- import java.io.ObjectOutput;
-
- public class Blip1 implements Externalizable {
- //public的構造方法,在回復對象的時候被調用。
- public Blip1() {
- System.out.println("Blip1 Constructor");
- }
-
- //在writeObject()方法的時候,會調用此方法
- public void writeExternal(ObjectOutput out) throws IOException {
- System.out.println("Blip1.writeExternal");
- }
-
- //在readObject()方法的時候,會調用此方法
- public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
- System.out.println("Blip1.readExternal");
- }
-
- }
- package externalizable;
-
- import java.io.Externalizable;
- import java.io.IOException;
- import java.io.ObjectInput;
- import java.io.ObjectOutput;
-
- public class Blip2 implements Externalizable {
- //此構造方法不是public的
- Blip2() {
- System.out.println("Blip2 Constructor");
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- System.out.println("Blip2.writeExternal");
- }
-
- public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
- System.out.println("Blip2.readExternal");
- }
- }
- package externalizable;
-
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
-
- public class Blips {
- public static void main(String[] args) {
- System.out.println("Constructing objects:");
- Blip1 b1 = new Blip1();
- Blip2 b2 = new Blip2();
- try {
- ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(
- "Blips.out"));
- System.out.println("Saving objects:");
- o.writeObject(b1);
- o.writeObject(b2);
- o.close();
- // Now get them back:
- ObjectInputStream in = new ObjectInputStream(new FileInputStream(
- "Blips.out"));
- System.out.println("Recovering b1:");
- b1 = (Blip1) in.readObject();
- // OOPS! Throws an exception:
- // !System.out.println("Recovering b2:");
- // !b2 = (Blip2) in.readObject();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
輸入的結果為:
Constructing objects:
Blip1 Constructor
Blip2 Constructor
Saving objects:
Blip1.writeExternal
Blip2.writeExternal
Recovering b1:
Blip1 Constructor
Blip1.readExternal