JAVA編程技術(shù)基礎(chǔ):探究JAVA串行化的細(xì)節(jié)

字號(hào):

串行化是java.io包中的一部分,它被用來將對(duì)象轉(zhuǎn)換成一串字節(jié)。在串行化的過程中,將一個(gè)實(shí)體轉(zhuǎn)變成一系列表示對(duì)象的字節(jié),這些字節(jié)可以寫入文檔以備后用,通過網(wǎng)絡(luò)連接傳輸?shù)狡渌绦颍脕韺?duì)初始對(duì)象進(jìn)行拷貝等等。
    如果你需要串行化一個(gè)類,那么就必須對(duì)這個(gè)類執(zhí)行java.io.Serializable,并且提供一個(gè)無爭議的構(gòu)造器。Serializable接口不需要任何方法,因此你的這個(gè)類不再需要?jiǎng)e的了。
    如果你有一個(gè)簡單的類似bean的類,而這個(gè)類僅僅是把原始的、可串行化對(duì)象作為屬性,那么你就不需要再做別的了。當(dāng)你需要將對(duì)象串行化為一系列字節(jié)或由一系列字節(jié)串行化而來時(shí),Java可以負(fù)責(zé)所有的細(xì)節(jié)。
    你可能會(huì)遇到的兩個(gè)問題
    串行化可能變得復(fù)雜得多。對(duì)于串行化,你通常會(huì)遇到兩個(gè)常有的問題:類版本和復(fù)雜對(duì)象。
    版本可能是你將碰到的第一個(gè)問題。譬如說,如果你在將實(shí)體串行化到一個(gè)磁盤之后,給你的類添加一種方法或?qū)傩?,然后想將串行化?shí)體存儲(chǔ)回內(nèi)存中,你將得到一個(gè)java.io.InvalidClassException。之所以會(huì)出現(xiàn)這個(gè)錯(cuò)誤,是因?yàn)槟愕念惖陌姹疽呀?jīng)改變。這個(gè)問題可以得到解決,但是你必須花一些功夫。說得更詳細(xì)一點(diǎn)就是檢查Java對(duì)象串行化細(xì)節(jié)。
    第二個(gè)可能的問題是,你的類是否有一些虛擬機(jī)不知道怎么串行化的狀態(tài)信息。如果是那樣,你可以通過以下兩種方法來完成讀寫類的實(shí)例的任務(wù)。
    private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
     private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
    注意,這兩種方法是私有的,串行化是特殊的。如果你想了解情況,就請(qǐng)看java.io.ObjectOutputStream和java.io.ObjectInputStream的源代碼,并且一定要閱讀關(guān)于java.io.Serializable的javadoc的內(nèi)容。
    以下是一個(gè)可以供你進(jìn)行實(shí)驗(yàn)的完整串行化例子:
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.EOFException;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.util.Random;
    public class SerializableTipHelper {
     private static final String STORE_FILE = "bytes.out";
     private static final boolean VERBOSE = true;
     public static void main(String[] args) {
     if ( args.length != 1 && args.length != 2 ) {
     System.out.println("use: SerializableTipHelper (read|write)
     [numberToWrite]");
     return;
     }
     if ( args[0].equals("write") ) {
     try {
     write(Integer.parseInt(args[1]));
     }
     catch (IOException e) {
     e.printStackTrace();
     }
     }
     // defaults to read
     else {
     try {
     read();
     }
     catch (IOException e) {
     e.printStackTrace();
     }
     catch (ClassNotFoundException e) {
     e.printStackTrace();