|
出于很多原因我們想使用自定義的序列化方法取代Java默認的機制。一個最常見的原因是提高性能,而另一個原因是有時候我們無法使用默認的序列化方法。在這篇文章中,我們具體來討論怎樣通過定制的序列化方法,對一個較大的、帶有不可序列化屬性的對象進行序列化。 下面這段代碼定義了一個簡單的類。它可以把一個給定的對象序列化到一個指定的文件,或者從相同的文件中把對象反序列化出來。在這片文章中,我將使用這個類進行演示。 SerializationDemonstrator.java
下面這段代碼給出了一個使用SerializationDemonstrator類序列化和反序列化標準的Java字符串的例子。字符串是支持序列化的。代碼之后的截圖顯示了在Netbeans中運行該類的serialize和deserialize方法后的輸出。 Running SerializationDemonstrator Methods on String
下面這兩段代碼定義了Person和CityState兩個類。CityState是Person的一個屬性。可以看到盡管Person實現(xiàn)了Serializable接口,CityState卻沒有。 Person.java
CityState.java
下面這段代碼演示了使用SerializationDemonstrator序列化Person類。由于包含了一個不可序列化的屬性CityState,在之后截圖里,我們可以看到Netbean拋出了異常。 Running SerializationDemonstrator Methods on Serializable Person with Non-Serializable CityState
在這個例子里,由于CityState類是我們自己寫的,我們可以使它支持序列化。但是如果這個類屬于一個第三方的框架或者庫,我們就很難去修改這個類。但是我們可以修改Person類,通過使用自定義的序列化和反序列化方法,使它和CityState類一起正常工作。下面這段代碼定義了一個從Person類改過來的SerializablePerson類。 SerializablePerson.java
在上面這段代碼中,SerializablePerson有自定義的writeobject和readObject方法。它們以適當?shù)姆绞教幚鞢ityState的序列化和反序列化。下面這段代碼使用SerializationDemonstrator運行了這個類,我們可以看到這次的運行是成功的。 Running SerializationDemonstrator on SerializablePerson
上面描述的這個方法可以允許我們在一個可序列化的類中使用不可序列化的屬性,而且不需要transient?,F(xiàn)在看上去已經(jīng)挺不錯了,但是如果前面這個CityState要在多個需要序列化的類中使用,更好的方式是用一個支持序列化的Decorator去修飾CityState。然后在那些需要做序列化的類中使用這個Decorator。下面這段代碼定義了SerializableCityState。它是CityState的一個支持序列化的Decorator版本。 SerializableCityState.java
這個可序列化的Decorator可以在Person類中直接使用。由于所有的屬性都支持序列化,Person類可以使用默認的序列化方法。下面這段代碼定義了一個從Person類改過來的Person2類。 Person2.java
下面這段代碼運行了這個類。之后是NetBeans輸出的截圖。 Running SerializationDemonstrator Against Person2/SerializableCityState
通過使用定制的序列化方法,可以在不使用transient的情況下,對一個帶有不可序列化屬性的類進行序列化。當你要在一個需要序列化的類中使用不可序列化的類型,并且這些類型不能被修改時,這是一個有用的技術(shù)。 |
|
|