Java 序列化

Java 提供了一種對象序列化的機制,該機制中,一個對象可以被表示為一個字節(jié)序列街氢,該字節(jié)序列包括該對象的數(shù)據(jù)、有關對象的類型的信息和存儲在對象中數(shù)據(jù)的類型睦袖。

將序列化對象寫入文件之后,可以從文件中讀取出來荣刑,并且對它進行反序列化馅笙,也就是說伦乔,對象的類型信息、對象的數(shù)據(jù)董习,還有對象中的數(shù)據(jù)類型可以用來在內(nèi)存中新建對象烈和。

整個過程都是 Java 虛擬機(JVM)獨立的,也就是說皿淋,在一個平臺上序列化的對象可以在另一個完全不同的平臺上反序列化該對象招刹。

類 ObjectInputStream 和 ObjectOutputStream 是高層次的數(shù)據(jù)流,它們包含反序列化和序列化對象的方法窝趣。

ObjectOutputStream 類包含很多寫方法來寫各種數(shù)據(jù)類型疯暑,但是一個特別的方法例外:

public final void writeObject(Object x) throws IOException

上面的方法序列化一個對象,并將它發(fā)送到輸出流哑舒。相似的 ObjectInputStream 類包含如下反序列化一個對象的方法:

public final Object readObject() throws IOException, 
                                 ClassNotFoundException

該方法從流中取出下一個對象妇拯,并將對象反序列化。它的返回值為Object洗鸵,因此越锈,你需要將它轉(zhuǎn)換成合適的數(shù)據(jù)類型。
為了演示序列化在Java中是怎樣工作的膘滨,我將使用之前教程中提到的Employee類甘凭,假設我們定義了如下的Employee類,該類實現(xiàn)了Serializable 接口火邓。

請注意丹弱,一個類的對象要想序列化成功,必須滿足兩個條件:

該類必須實現(xiàn) java.io.Serializable 對象贡翘。

該類的所有屬性必須是可序列化的蹈矮。如果有一個屬性不是可序列化的,則該屬性必須注明是短暫的泛鸟。

如果你想知道一個 Java 標準類是否是可序列化的,請查看該類的文檔踊东。檢驗一個類的實例是否能序列化十分簡單北滥, 只需要查看該類有沒有實現(xiàn) java.io.Serializable接口。

序列化對象

ObjectOutputStream 類用來序列化一個對象闸翅,如下的 SerializeDemo 例子實例化了一個 Employee 對象再芋,并將該對象序列化到一個文件中。

該程序執(zhí)行后坚冀,就創(chuàng)建了一個名為 employee.ser 文件济赎。該程序沒有任何輸出,但是你可以通過代碼研讀來理解程序的作用。

注意: 當序列化一個對象到文件時司训, 按照 Java 的標準約定是給文件一個 .ser 擴展名构捡。

import java.io.*;

// 序列化對象
public class SerializeDemo {
    public static void main(String[] args) {

        Employee e = new Employee();
        e.name = "shavekevin";
        e.address = "北京 朝陽";
        e.SSN = 123;
        e.number = 9527;
        try {
            FileOutputStream fileOut =
            new FileOutputStream("/tmp/employee.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(e);
            out.close();
            fileOut.close();
            System.out.printf("Serialized data is saved in /tmp/employee.ser");

        } catch (Exception i) {
            // TODO: handle exception
        }

    }
}

編譯后的結(jié)果為:

Serialized data is saved in /tmp/employee.ser

反序列化對象

下面的 DeserializeDemo 程序?qū)嵗朔葱蛄谢?tmp/employee.ser 存儲了 Employee 對象。

import java.io.*;

// 反序列化對象
public class DeserializeDemo {
    public static void main(String[] args) {

        Employee e = null;
        try {
            FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            e = (Employee) in.readObject();
            in.close();
            fileIn.close();
        } catch (IOException i) {
            i.printStackTrace();
            return;
        } catch (ClassNotFoundException c) {
            System.out.println("Employee class not found");
            c.printStackTrace();
            return;
        }
        System.out.println("Deserialized Employee...");
        System.out.println("Name: " + e.name);
        System.out.println("Address: " + e.address);
        System.out.println("SSN: " + e.SSN);
        System.out.println("Number: " + e.number);
    }
}

編譯后的結(jié)果為:

Deserialized Employee...
Name: shavekevin
Address: 北京 朝陽
SSN: 0
Number: 9527

這里要注意以下要點:
這里要注意以下要點:

readObject() 方法中的 try/catch代碼塊嘗試捕獲 ClassNotFoundException 異常壳猜。對于 JVM 可以反序列化對象勾徽,它必須是能夠找到字節(jié)碼的類。如果JVM在反序列化對象的過程中找不到該類统扳,則拋出一個 ClassNotFoundException 異常喘帚。

注意,readObject() 方法的返回值被轉(zhuǎn)化成 Employee 引用咒钟。

當對象被序列化時吹由,屬性 SSN 的值為 123,但是因為該屬性是短暫的盯腌,該值沒有被發(fā)送到輸出流溉知。所以反序列化后 Employee 對象的 SSN 屬性為 0。

源地址:Java 序列化
github地址:Java學習

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腕够,一起剝皮案震驚了整個濱河市级乍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帚湘,老刑警劉巖玫荣,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異大诸,居然都是意外死亡捅厂,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門资柔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來焙贷,“玉大人,你說我怎么就攤上這事贿堰≌奚郑” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵羹与,是天一觀的道長故硅。 經(jīng)常有香客問我,道長纵搁,這世上最難降的妖魔是什么吃衅? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮腾誉,結(jié)果婚禮上徘层,老公的妹妹穿的比我還像新娘峻呕。我一直安慰自己,他們只是感情好惑灵,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布山上。 她就那樣靜靜地躺著眼耀,像睡著了一般英支。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哮伟,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天干花,我揣著相機與錄音,去河邊找鬼楞黄。 笑死池凄,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的鬼廓。 我是一名探鬼主播肿仑,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼碎税!你這毒婦竟也來了尤慰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤雷蹂,失蹤者是張志新(化名)和其女友劉穎伟端,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匪煌,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡责蝠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了萎庭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霜医。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖驳规,靈堂內(nèi)的尸體忽然破棺而出肴敛,到底是詐尸還是另有隱情,我是刑警寧澤达舒,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布值朋,位于F島的核電站,受9級特大地震影響巩搏,放射性物質(zhì)發(fā)生泄漏昨登。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一贯底、第九天 我趴在偏房一處隱蔽的房頂上張望丰辣。 院中可真熱鬧撒强,春花似錦、人聲如沸笙什。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琐凭。三九已至芽隆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間统屈,已是汗流浹背胚吁。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留愁憔,地道東北人腕扶。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像吨掌,于是被迫代替她去往敵國和親半抱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容