<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 297,  comments - 1618,  trackbacks - 0
     

    當(dāng)兩個進(jìn)程在進(jìn)行遠(yuǎn)程通信時,彼此可以發(fā)送各種類型的數(shù)據(jù)。無論是何種類型的數(shù)據(jù),都會以二進(jìn)制序列的形式在網(wǎng)絡(luò)上傳送。發(fā)送方需要把這個Java對象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)絡(luò)上傳送;接收方則需要把字節(jié)序列再恢復(fù)為Java對象。

    Java對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化

    把字節(jié)序列恢復(fù)為Java對象的過程稱為對象的反序列化

    對象的序列化主要有兩種用途:

    1) 把對象的字節(jié)序列永久地保存到硬盤上,通常存放在一個文件中;

    2) 在網(wǎng)絡(luò)上傳送對象的字節(jié)序列。

    一.             JDK類庫中的序列化API

    java.io.ObjectOutputStream代表對象輸出流,它的writeObject(Object obj)方法可對參數(shù)指定的obj對象進(jìn)行序列化,把得到的字節(jié)序列寫到一個目標(biāo)輸出流中。

    java.io.ObjectInputStream代表對象輸入流,它的readObject()方法從一個源輸入流中讀取字節(jié)序列,再把它們反序列化為一個對象,并將其返回。、

    只有實(shí)現(xiàn)了SerializableExternalizable接口的類的對象才能被序列化。Externalizable接口繼承自Serializable接口,實(shí)現(xiàn)Externalizable接口的類完全由自身來控制序列化的行為,而僅實(shí)現(xiàn)Serializable接口的類可以采用默認(rèn)的序列化方式

    對象序列化包括如下步驟:

    1) 創(chuàng)建一個對象輸出流,它可以包裝一個其他類型的目標(biāo)輸出流,如文件輸出流;

    2) 通過對象輸出流的writeObject()方法寫對象。

    對象反序列化的步驟如下:

    1) 創(chuàng)建一個對象輸入流,它可以包裝一個其他類型的源輸入流,如文件輸入流;

    2) 通過對象輸入流的readObject()方法讀取對象。

    下面讓我們來看一個對應(yīng)的例子,類的內(nèi)容如下:

    import java.io.*;

    import java.util.Date;

    /**

     * 對象的序列化和反序列化測試類.    

     * @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>

     * @version 1.0

     * Creation date: 2007-9-15 - 下午21:45:48

     */

    public class ObjectSaver {

           /**

            * @param args

            * @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>

            * Creation date: 2007-9-15 - 下午21:45:37

            */

           public static void main(String[] args) throws Exception {

                  ObjectOutputStream out = new ObjectOutputStream

                         (new FileOutputStream("D:""objectFile.obj"));

                  //序列化對象

                  Customer customer = new Customer("阿蜜果", 24);

                  out.writeObject("你好!");

                  out.writeObject(new Date());

                  out.writeObject(customer);

                  out.writeInt(123); //寫入基本類型數(shù)據(jù)

                  out.close();

                  //反序列化對象

                  ObjectInputStream in = new ObjectInputStream

                         (new FileInputStream("D:""objectFile.obj"));

                  System.out.println("obj1=" + (String) in.readObject());

                  System.out.println("obj2=" + (Date) in.readObject());

                  Customer obj3 = (Customer) in.readObject();

                  System.out.println("obj3=" + obj3);

                  int obj4 = in.readInt();

                  System.out.println("obj4=" + obj4);

                  in.close();

           }

    }

    class Customer implements Serializable {

           private String name;

           private int age;

           public Customer(String name, int age) {

                  this.name = name;

                  this.age = age;

           }

           public String toString() {

                  return "name=" + name + ", age=" + age;

           }

    }

           輸出結(jié)果如下:

    obj1=你好!

    obj2=Sat Sep 15 22:02:21 CST 2007

    obj3=name=阿蜜果, age=24

    obj4=123

        因此例比較簡單,在此不再詳述。

    二.實(shí)現(xiàn)Serializable接口

    ObjectOutputStream只能對Serializable接口的類的對象進(jìn)行序列化。默認(rèn)情況下,ObjectOutputStream按照默認(rèn)方式序列化,這種序列化方式僅僅對對象的非transient的實(shí)例變量進(jìn)行序列化,而不會序列化對象的transient的實(shí)例變量,也不會序列化靜態(tài)變量。

    當(dāng)ObjectOutputStream按照默認(rèn)方式反序列化時,具有如下特點(diǎn):

    1)              如果在內(nèi)存中對象所屬的類還沒有被加載,那么會先加載并初始化這個類。如果在classpath中不存在相應(yīng)的類文件,那么會拋出ClassNotFoundException;

    2)              在反序列化時不會調(diào)用類的任何構(gòu)造方法。

    如果用戶希望控制類的序列化方式,可以在可序列化類中提供以下形式的writeObject()readObject()方法。

    private void writeObject(java.io.ObjectOutputStream out) throws IOException

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

    當(dāng)ObjectOutputStream對一個Customer對象進(jìn)行序列化時,如果該對象具有writeObject()方法,那么就會執(zhí)行這一方法,否則就按默認(rèn)方式序列化。在該對象的writeObjectt()方法中,可以先調(diào)用ObjectOutputStreamdefaultWriteObject()方法,使得對象輸出流先執(zhí)行默認(rèn)的序列化操作。同理可得出反序列化的情況,不過這次是defaultReadObject()方法。

    有些對象中包含一些敏感信息,這些信息不宜對外公開。如果按照默認(rèn)方式對它們序列化,那么它們的序列化數(shù)據(jù)在網(wǎng)絡(luò)上傳輸時,可能會被不法份子竊取。對于這類信息,可以對它們進(jìn)行加密后再序列化,在反序列化時則需要解密,再恢復(fù)為原來的信息。

    默認(rèn)的序列化方式會序列化整個對象圖,這需要遞歸遍歷對象圖。如果對象圖很復(fù)雜,遞歸遍歷操作需要消耗很多的空間和時間,它的內(nèi)部數(shù)據(jù)結(jié)構(gòu)為雙向列表。

    在應(yīng)用時,如果對某些成員變量都改為transient類型,將節(jié)省空間和時間,提高序列化的性能。

    三.             實(shí)現(xiàn)Externalizable接口

    Externalizable接口繼承自Serializable接口,如果一個類實(shí)現(xiàn)了Externalizable接口,那么將完全由這個類控制自身的序列化行為。Externalizable接口聲明了兩個方法:

    public void writeExternal(ObjectOutput out) throws IOException

    public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException

    前者負(fù)責(zé)序列化操作,后者負(fù)責(zé)反序列化操作。

    在對實(shí)現(xiàn)了Externalizable接口的類的對象進(jìn)行反序列化時,會先調(diào)用類的不帶參數(shù)的構(gòu)造方法,這是有別于默認(rèn)反序列方式的。如果把類的不帶參數(shù)的構(gòu)造方法刪除,或者把該構(gòu)造方法的訪問權(quán)限設(shè)置為private、默認(rèn)或protected級別,會拋出java.io.InvalidException: no valid constructor異常。

    四.             可序列化類的不同版本的序列化兼容性

    凡是實(shí)現(xiàn)Serializable接口的類都有一個表示序列化版本標(biāo)識符的靜態(tài)變量:

    private static final long serialVersionUID;

    以上serialVersionUID的取值是Java運(yùn)行時環(huán)境根據(jù)類的內(nèi)部細(xì)節(jié)自動生成的。如果對類的源代碼作了修改,再重新編譯,新生成的類文件的serialVersionUID的取值有可能也會發(fā)生變化。

    類的serialVersionUID的默認(rèn)值完全依賴于Java編譯器的實(shí)現(xiàn),對于同一個類,用不同的Java編譯器編譯,有可能會導(dǎo)致不同的serialVersionUID,也有可能相同。為了提高哦啊serialVersionUID的獨(dú)立性和確定性,強(qiáng)烈建議在一個可序列化類中顯示的定義serialVersionUID,為它賦予明確的值。顯式地定義serialVersionUID有兩種用途:

    1)              在某些場合,希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有相同的serialVersionUID;

    2)              在某些場合,不希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有不同的serialVersionUID

    posted on 2007-09-16 09:34 阿蜜果 閱讀(29229) 評論(14)  編輯  收藏 所屬分類: Java


    FeedBack:
    # re: 對象的序列化和反序列化
    2007-09-16 10:04 | 久城
    GOOD!~

    本計劃這幾天也學(xué)習(xí)一下JAVA的序列化與反序列化呢,主要想實(shí)現(xiàn)兩個接口:
    String toXml(Object obj); // 把一個字符串以XML格式保存
    Object toObject(String str); // 把一個XML格式的字符串發(fā)序列化回對象

    因?yàn)閄ML在不同語言環(huán)境中都是可以交互的,所以可以方便不同語言之間數(shù)據(jù)對象的傳遞。LZ有興趣可以研究下,我再來學(xué)習(xí)哈哈。  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化
    2007-09-16 11:52 | BeanSoft
    啊. Java 里面已經(jīng)實(shí)現(xiàn)的有了啊.

    /*
    * @(#)BeanXML.java 1.00 2005-10-7
    *
    * Copyright 2005 BeanSoft Studio. All rights reserved.
    * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
    */
    package beansoft.xml;

    import java.beans.XMLDecoder;
    import java.beans.XMLEncoder;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.UnsupportedEncodingException;

    /**
    * BeanXML
    *
    * Chinese documents:
    *
    * @author BeanSoft
    * @version 1.00 2005-10-7
    */
    public class BeanXML {
    /**
    * 使用 java.beans.XMLEncoder 將 對象編碼為 XML.
    * @param bean 對象
    * @return String - 編碼后的 XML
    */
    public static String encodeBean(Object bean) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    XMLEncoder encoder = new XMLEncoder(out);
    encoder.writeObject(bean);
    encoder.close();

    return out.toString();
    }

    /**
    * 使用 java.beans.XMLDecoder 將 XML 解碼為 對象.
    * @param xml - 編碼后的 XML
    * @return Object 反編碼后的對象
    */
    public static Object decodeBean(String xml) {
    try {
    // FIXME 必須使用 GBK 解碼才對, 否則出來的文字是亂碼?
    XMLDecoder decoder = new XMLDecoder(new ByteArrayInputStream(xml.getBytes("GBK")));
    return decoder.readObject();
    } catch (UnsupportedEncodingException e) {
    }

    return null;
    }
    }
      回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化
    2007-09-16 21:45 | 孫健
    其實(shí)java編程思想里 把此解釋的已經(jīng)很清楚了!??!  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化
    2007-09-16 23:57 | 千里冰封
    序列化要研究的話,還可以研究得更深一些的
      回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化
    2007-09-17 08:13 | 久城
    @BeanSoft
    多謝BeanSoft兄。..^.^居然是兩年前的代碼,看來我真的是跟不上時代的步伐了哈哈。

    那兩個接口是一位講師留給我們的作業(yè),不想用JAVA封裝好的類實(shí)現(xiàn),想讓我們自己實(shí)現(xiàn)一個。我想老師的目的主要是想讓我們熟悉一下面向?qū)ο蠛蚃AVA反射機(jī)制吧。  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化[未登錄]
    2007-09-17 08:51 | 阿蜜果
    @久城
    多謝關(guān)注

    @千里冰封
    序列化蠻有意思的,呵呵,希望能來個下篇,研究得更深一點(diǎn)。

    @beansoft
    大師大師,嘻嘻,強(qiáng)。

    @孫健
    恩,在Thinking in java里面講得很清楚了,此篇是看孫MM的《Java網(wǎng)絡(luò)編程》其中的一章做的筆記,感覺有一些東西還沒講透。  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化[未登錄]
    2007-09-19 09:09 | javaapi.cn
    好文章!  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化
    2007-10-12 00:33 | sanha
    關(guān)于 用XmlEncoder和XmlDecoder來序列化和反序列化一個類
    的簡單實(shí)例
    http://nwsky.blog.sohu.com/66895243.html
    很簡單,也很有代表性,看看就明白了.  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化
    2008-01-24 13:19 | 怎么羨慕天空的飛鳥
    在百度上找這方面的介紹,結(jié)果又找到你這了。^_^  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化
    2008-04-12 23:47 | ehuan
    @久城
    貌似你說的不是序列化,而是裝箱和拆箱  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化[未登錄]
    2008-10-29 10:00 | Wing
    總結(jié)得很清楚,非常感謝  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化
    2009-02-22 09:01 | charles zhu
    寫的很好,很簡練。。。謝謝  回復(fù)  更多評論
      
    # 寫一個java程序要求如下
    2012-04-11 22:02 | 814250785@qq.com
    1.把一個對象存儲txt文件;2.把對象讀出;3.追加一個對象txt;4.把兩個對象全部讀出;5.一組對象先存入list,再追加到txt;6.把所有對象全部讀出。 幫我把這個程序?qū)懗鰜戆桑x謝了  回復(fù)  更多評論
      
    # re: 對象的序列化和反序列化[未登錄]
    2014-10-27 17:16 | 1
    <2007年9月>
    2627282930311
    2345678
    9101112131415
    16171819202122
    23242526272829
    30123456

          生活將我們磨圓,是為了讓我們滾得更遠(yuǎn)——“圓”來如此。
          我的作品:
          玩轉(zhuǎn)Axure RP  (2015年12月出版)
          

          Power Designer系統(tǒng)分析與建模實(shí)戰(zhàn)  (2015年7月出版)
          
         Struts2+Hibernate3+Spring2   (2010年5月出版)
         

    留言簿(263)

    隨筆分類

    隨筆檔案

    文章分類

    相冊

    關(guān)注blog

    積分與排名

    • 積分 - 2294312
    • 排名 - 3

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲免费网站在线观看| 美女黄色免费网站| 99精品一区二区免费视频| 亚洲午夜福利在线观看| 黄视频在线观看免费| 91麻豆国产自产在线观看亚洲 | 国产免费人成视频在线播放播| 国产精品国产免费无码专区不卡| 亚洲免费综合色在线视频| 免费的涩涩视频在线播放| 美女视频黄频a免费观看| 亚洲精品无码你懂的网站| 亚洲男人的天堂在线va拉文| 精品国产免费人成网站| 亚洲AV福利天堂一区二区三 | 久久午夜无码免费| 精品亚洲国产成AV人片传媒| 免费阿v网站在线观看g| 中文字幕无码亚洲欧洲日韩| 日韩精品免费一区二区三区| 人人鲁免费播放视频人人香蕉| 亚洲精品国产精品乱码在线观看| 99国产精品免费观看视频| 精品日韩99亚洲的在线发布| 四虎影视永久免费观看地址 | 免费无码又爽又黄又刺激网站| 亚洲综合另类小说色区| 99视频免费播放| 亚洲av无码日韩av无码网站冲 | 国产精品永久免费10000| 亚洲av综合av一区二区三区| 亚洲一级片免费看| 日本人的色道免费网站| 欧洲亚洲综合一区二区三区| 国产亚洲美女精品久久久久狼| 在线视频观看免费视频18| 免费国产污网站在线观看不要卡| 亚洲免费精彩视频在线观看| 日本成人在线免费观看| GOGOGO免费观看国语| 一本色道久久88—综合亚洲精品|