<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x

    Java自定義序列化行為解析

    發布時間:2011-5-1 20:00    發布者:1046235000
    關鍵詞: java , 自定義序列化行為
    正常情況下,一個類實現java序列化很簡單,只需要implements Serializable接口即可,之后該類在跨jvm 的傳輸過程中會遵照默認java序列化規則序列化和反序列化;不同jvm 版本之間序列化方式稍有不同,但基本上都是兼容的。在某些特殊情況下,可能需要自定義序列化和反序列化的行為,看下面例子:
        Java代碼
        class AbstractSerializeDemo {
        private int x , y;
        public void init(int x , int y) {
        this.x = x;
        this.y = y;
        }
        public int getX () {
        return x;
        }
        public int getY () {
        return y;
        }
        public void printXY () {
        System.out.println("x:" + x + " ;y :" + y );
        }
        }
        public class SerializeDemo extends AbstractSerializeDemo implements
        Serializable {
        private int z ;
        public SerializeDemo() {
        super.init(10, 50 );
        z = 100 ;
        }
        public void printZ() {
        super.printXY ();
        System.out.println("z:" + z );
        }
        public static void main (String[] args ) throws IOException , ClassNotFoundException
        {
        ByteArrayOutputStream bos = new ByteArrayOutputStream ();
        ObjectOutputStream out = new ObjectOutputStream (bos );
        SerializeDemo sd = new SerializeDemo();
        sd.printZ ();
        out.writeObject (sd);
        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream
        (bos.toByteArray ()));
        SerializeDemo sd2 = (SerializeDemo ) in.readObject();
        sd2.printZ();
        }
        }

       這段程序表示了一個可序列化的類繼承自一個非序列化的有狀態超類,期望的結果是,子類序列化以后傳輸并反序列化回來,原先的值域包括超類的值域都保持不變。
        但是輸出是:
        Java代碼
        x :10;y :50
        z :100
        x :0 ;y :0
        z :100 結果和期望不符,子類的值域保留下來了,但是超類的值域丟失了,這對jvm 來說是正常的,因為超類不可序列化;為了解決這個問題,只能自定義序列化行為,具體做法是在SerializeDemo里加入以下代碼:
        Java代碼
        private void writeObject(ObjectOutputStream os ) throws IOException
        {
        os.defaultWriteObject ();//java對象序列化默認操作
        os.writeInt (getX());
        os.writeInt (getY());
        }
        private void readObject (ObjectInputStream is) throws IOException
        ,ClassNotFoundException {
        is.defaultReadObject();//java對象反序列化默認操作
        int x=is.readInt();
        int y=is.readInt();
        super.init(x ,y );
        } writeObject 和readObject方法為JVM 會在序列化和反序列化java對象時
        會分別調用的兩個方法,修飾符都是private ,沒錯。我們在序列化的默認動作之后將超類里的兩個值域x 和y 也寫入object流;與之對應在反序列化的默認操作之后讀入x 和y 兩個值,然后調用超類的初始化方法。
        再次執行程序之后的輸出為:
        Java代碼
        x :10;y :50
        z :100
        x :10;y :50
        z :100 另外還有兩個自定義序列化方法writeReplace和readResolve ,分別用來在序列化之前替換序列化對象和在反序列化之后的對返回對象的處理。一般可以用來避免singleTon 對象跨jvm 序列化和反序列化時產生多個對象實例,事實上singleTon 的對象一旦可序列化,它就不能保證singleTon 了。JVM 的Enum實現里就是重寫了readResolve 方法,由JVM 保證Enum的值都是singleTon 的,所以建議多使用Enum代替使用writeReplace和readResolve 方法。
        Java代碼
        private Object readResolve()
        {
        return INSTANCE ;
        }
        private Object writeReplace (){
        return INSTANCE ;
        }
        注:writeReplace調用在writeObject 前;readResolve 調用在readObject
        之后。
    本文地址:http://www.portaltwn.com/thread-64041-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • EtherCAT®和Microchip LAN925x從站控制器介紹培訓教程
    • MPLAB®模擬設計器——在線電源解決方案,加速設計
    • 讓您的模擬設計靈感,化為觸手可及的現實
    • 深度體驗Microchip自動輔助駕駛應用方案——2025巡展開啟報名!
    • 貿澤電子(Mouser)專區
    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷