2012-10-31 71 views
2

我正在閱讀關於DD的維基百科文章,並跳轉到最後給出的"Double dispatch in Java and an example"鏈接。下面的序列化實例的描述似乎很困惑,我說:Java示例中的雙重派遣

A a = new A(); 
ObjectOutputStream oos = new ObjectOutputStream(); 
oos.writeObject(a); 

這裏的描述:

爲了序列A,ObjectOutputStream首先查看如果方法writeObject(ObjectOutputStream oos)存在。如果確實如此,那麼它會以自己作爲參數來調用該方法。然後writeObject方法將呼叫分派回ObjectOutputStream(從而使其成爲雙派遣)。在做這個非常簡單的回調時,ObjectOutputStream曾經說過:「我將委託給你的責任是將你的狀態寫入這個流。」在做出這個簡單的選擇時,ObjectOutputStream已經從我們的對象A中解耦。對象A反過來說好吧,這裏是我想寫在流中的一些狀態。如果該值是一個基元,則可以通過寫入方法的重載來處理它。如果沒有,則來回可以在對象圖中的下一級繼續,直到所有有用狀態已經被放置在流上。

我在猜測描述可能會令人困惑,因爲描述的是幕後發生的事情,而不是呈現的代碼,因爲否則它似乎沒有多大意義。以下是令我困惑的部分:

  • ObjectOutputStream先看看是否存在方法writeObject(ObjectOutputStream oos)」。爲什麼ObjectOutputStream需要檢查此方法的存在,因爲它是它自己的方法?
  • 「如果是這樣,那麼它將自己作爲參數調用該方法」。它看起來像它叫writeObjectA作爲參數的實例。回到前一個項目,爲什麼它會尋找writeObject簽名與ObjectOutputStream arg如果它正在調用A的實例?
  • 「該writeObject方法然後調用回撥到ObjectOutputStream(因此使這是一個雙派遣)」。同樣,writeObject方法屬於ObjectOutputStream類,所以我沒有看到它如何被「分派回ObjectOutputStream」,因爲這似乎是原始目的地。

我在這裏只是錯過了一些基本的東西,還是這是一個寫得不好的/描述的例子?如果這是一個不好的例子,我想修改維基百科文章以指向更好的文章,所以請隨時提供建議。

謝謝。

+0

感謝您的好答案。我仍然相信,如果甚至對基本機制進行了簡短的描述/解釋,那麼這篇文章就會好得多。 – WXB13

+0

它在技術上是準確的,但措辭笨拙。你說得對,一兩個例子會有所幫助。 –

回答

4

回答您的問題依次是:

  1. ObjectOutputStream.writeObject(Object)檢查它的參數(使用反射),以確定對象實現writeObject(ObjectOutputStream)。也就是說,它或多或少會問這個對象:「你知道如何將你的結構寫入ObjectOutputStream?「

  2. 如果答案是‘是’,那麼ObjectOutputStream調用對象的writeObject(ObjectOutputStream)方法,傳遞本身(ObjectOutputStream,不是對象)作爲參數。基本上,它說:」好。寫下您的結構給我。」

  3. 在對ObjectOutputStream對象調用寫的自身元素writeObject(ObjectOutputStream)的實現。這是不應該再打電話oos.writeObject(this)

例如,假設我有過這樣的對象:

class A { 
    int x; 
} 

如果我要使它能夠自己寫一個ObjectOutputStream,我可能會展開這樣的:

class A implements Serializable { 
    int x; 
    private void writeObject(ObjectOutputStream stream) throws IOException { 
     stream.writeInt(x); 
    } 
} 

然後,代碼:

A a = new A(); 
ObjectOutputStream oos = . . .; 
oos.writeObject(a); 

將使用writeObject方法A類寫a,而不是使用反射寫A的所有的(非瞬態)的字段(在此情況下然而,就不會有差異)

+0

解釋它。謝謝。 – WXB13

1

Serializable接口的文檔:

類的序列化和反序列化 過程中需要進行特殊處理必須實現這些 準確簽名的特殊方法:

私人無效的writeObject(java.io.ObjectOutputStream中出) 拋出IOException異常私人無效的readObject(java.io.ObjectInputStream中in) throws IOException,ClassNotFoundException; private void readObjectNoData() throws ObjectStreamException;

如果你想讓你的類可串行化實現接口就夠了。但是,如果你想讓(類的)對象告訴輸出流如何序列化它自己的狀態,那麼它應該實現這些方法。

+0

啊是的。我應該有RTFM(我通常會這樣做)。謝謝。 – WXB13