2013-08-18 17 views
4

我無法理解Java 1.6中Serialization的基本知識。Java中的序列化基礎知識不明白

下面是含有Collar類的一個實例變量的Dog類別:

Dog.java

public class Dog implements Serializable { 

private Collar collar; 

public Collar getCollar() { 
    return collar; 
} 

public void setCollar(Collar collar) { 
    this.collar = collar; 
} 

} 

套環類不實現Serializable接口,如下所示:

Collar.java

public class Collar { 

private int size; 

public int getSize() { 
    return size; 
} 

public void setSize(int size) { 
    this.size = size; 
} 

} 

現在,當我試圖序列化Dog那麼爲什麼它不會拋出NotSerializableException?根據合同,整個對象圖應該實現Serializable,但是我的Collar類不能滿足這個要求。

下面是這個演示的主要方法:

public static void main(String[] args) { 
    try { 
     FileOutputStream fs = new FileOutputStream("E:\\test.ser"); 
     ObjectOutputStream os = new ObjectOutputStream(fs); 
     Dog dog = new Dog(); 
     // No exception thrown here, WHY? 
     // test.ser file is getting created properly. 
     os.writeObject(dog); 

     FileInputStream fis = new FileInputStream("E:\\test.ser"); 
     ObjectInputStream ois = new ObjectInputStream(fis); 
     Dog dog1 = (Dog)ois.readObject(); 
     // Here I am getting a null Collar object 
     Collar c1 = dog1.getCollar(); 

請解釋這一點,我完全糊塗了,而試圖實現所有的理論東西:(

+1

請在讀取文件之前添加這些行'outputStream.flush();''outputStream.close();'然後回報您的發現 – Multithreader

+0

您自己說過:整個* object graph *必須是可序列化的,而不是你的代碼碰巧提到的所有類。 –

+0

@Multithreader如果我添加上面提到的兩行,沒有區別 – WhoAmI

回答

2

看來您對對象圖的概念有誤解。在該圖中,節點是實例而不是類)並且邊緣由參考類型實例變量的值形成。

應用到您的例子,

Dog dog = new Dog(); 

創建由單個節點,所述Dog實例的對象圖。 collar變量是null所以它的值不會形成邊緣沒有另一個節點。但是,如果添加一行如

dog.setCollar(new Collar()); 

現在你的對象圖包含兩個節點,通過在collar實例變量的值形成的邊緣連接。

現在,所有這些應用於序列化意味着您發佈的示例將序列化所有節點都可序列化的單節點對象圖形,但如果添加了一個領子,該圖形將包含一個非序列化節點,得到你期望的異常。

+0

好的和清楚的解釋! – WhoAmI

9

可能是因爲您dog不有collar

與嘗試

Dog dog = new Dog(); 
dog.setCollar(new Collar()); 
+1

有趣。所以序列化是關於實例化的類,而不是它們的聲明。回想起來,這是有道理的,因爲我們可以用附件替換Collar,並且讓Collar和FoodBowl成爲附件的實現者。附件不值得序列化的Jack - 我們需要實際的具體類 –