天天看點

淺析Java序列化機制

    Java當中的序列化,其主要的作用是将類的執行個體進行無損傳輸,或者說就是通過Java的序列化機制,Java類的執行個體可以通過Object流來傳輸和重新擷取,而不會損壞類的執行個體。

    首先,我們看看什麼樣的類是序列化類,

      1.A類自身實作了Serializable接口的類;

      2.A類自身沒有實作Serializable接口,但其父類實作了Serializable接口的類;

    以上兩種,我們認為是類A是序列化類。

    在SCJP考試當中就有一道關于序列化的題目:

    import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

class Food {

Food() {

System.out.print("1");

}

}

class Fruit extends Food implements Serializable {

Fruit() {

System.out.print("2");

}

}

public class Banana2 extends Fruit {

int size = 42;

public static void main(String[] args) {

Banana2 b = new Banana2();

b.serializeBanana2(b); // assume correct serialization

b = b.deserializeBanana2(b); // assume correct

System.out.println(" restored " + b.size + " ");

}

// more Banana2 methods

public static void serializeBanana2(Banana2 b) {

try {

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("c:/a.txt"));

out.writeObject(b);

} catch (Exception e) {

e.printStackTrace();

}

}

public static Banana2 deserializeBanana2(Banana2 b) {

try {

ObjectInputStream in = new ObjectInputStream(new FileInputStream("c:/a.txt"));

return (Banana2) in.readObject();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

這道題的輸出結果是:121 restored 42

    從運作結果來看:前連個數字12是顯而易見的,在new Banana2()的時候執行的,但是第三個1就不好了解了,其實,如果從多态的角度考慮,也不難了解,因為反序列化是要得到原類的執行個體,而這就需要在反序列化之前就得聲明一個原始類或者原始類的父類的一個執行個體,在從Java多态的機制考慮,通過父類(基類)聲明就容易了解了。

    當然,這樣對父類也有相應的要求,如果類A實作了序列化接口,而A的父類沒有實作序列化接口,那麼,在反序列化A的執行個體的時候,會首先執行一下A的父類的無參構造,是以這就要求:A的父類必須具備一個無參的構造函數,否則報錯。如果父類也實作了序列化接口,那麼在反序列化的時候,父類構造不會被執行。