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

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

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

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評(píng)論 - 101, 引用 - 0
    數(shù)據(jù)加載中……

    Java對(duì)象序列化

     在網(wǎng)上看了很多有關(guān)序列化的文章,我自己也寫(xiě)了兩篇,現(xiàn)在感覺(jué)這些文章都沒(méi)有很好的把序列化說(shuō)清楚(包括我自己在內(nèi)),所以在此我將總結(jié)前人以及自己的經(jīng)驗(yàn),用更淺顯易懂的語(yǔ)言來(lái)描述該機(jī)制,當(dāng)然,仍然會(huì)有不好的地方,希望你看后可以指出,作為一名程序員應(yīng)該具有不斷探索的精神和強(qiáng)烈的求知欲望!

    序列化概述:

          簡(jiǎn)單來(lái)說(shuō)序列化就是一種用來(lái)處理對(duì)象流的機(jī)制,所謂對(duì)象流也就是將對(duì)象的內(nèi)容進(jìn)行流化,流的概念這里不用多說(shuō)(就是I/O),我們可以對(duì)流化后的對(duì)象進(jìn)行讀寫(xiě)操作,也可將流化后的對(duì)象傳輸于網(wǎng)絡(luò)之間(注:要想將對(duì)象傳輸于網(wǎng)絡(luò)必須進(jìn)行流化)!在對(duì)對(duì)象流進(jìn)行讀寫(xiě)操作時(shí)會(huì)引發(fā)一些問(wèn)題,而序列化機(jī)制正是用來(lái)解決這些問(wèn)題的!

    問(wèn)題的引出:

          如上所述,讀寫(xiě)對(duì)象會(huì)有什么問(wèn)題呢?比如:我要將對(duì)象寫(xiě)入一個(gè)磁盤(pán)文件而后再將其讀出來(lái)會(huì)有什么問(wèn)題嗎?別急,其中一個(gè)最大的問(wèn)題就是對(duì)象引用!舉個(gè)例子來(lái)說(shuō):假如我有兩個(gè)類,分別是A和B,B類中含有一個(gè)指向A類對(duì)象的引用,現(xiàn)在我們對(duì)兩個(gè)類進(jìn)行實(shí)例化{ A a = new A(); B b = new B(); },這時(shí)在內(nèi)存中實(shí)際上分配了兩個(gè)空間,一個(gè)存儲(chǔ)對(duì)象a,一個(gè)存儲(chǔ)對(duì)象b,接下來(lái)我們想將它們寫(xiě)入到磁盤(pán)的一個(gè)文件中去,就在寫(xiě)入文件時(shí)出現(xiàn)了問(wèn)題!因?yàn)閷?duì)象b包含對(duì)對(duì)象a的引用,所以系統(tǒng)會(huì)自動(dòng)的將a的數(shù)據(jù)復(fù)制一份到b中,這樣的話當(dāng)我們從文件中恢復(fù)對(duì)象時(shí)(也就是重新加載到內(nèi)存中)時(shí),內(nèi)存分配了三個(gè)空間,而對(duì)象a同時(shí)在內(nèi)存中存在兩份,想一想后果吧,如果我想修改對(duì)象a的數(shù)據(jù)的話,那不是還要搜索它的每一份拷貝來(lái)達(dá)到對(duì)象數(shù)據(jù)的一致性,這不是我們所希望的!

    以下序列化機(jī)制的解決方案:

    1.保存到磁盤(pán)的所有對(duì)象都獲得一個(gè)序列號(hào)(1, 2, 3等等)

    2.當(dāng)要保存一個(gè)對(duì)象時(shí),先檢查該對(duì)象是否被保存了。

    3.如果以前保存過(guò),只需寫(xiě)入"與已經(jīng)保存的具有序列號(hào)x的對(duì)象相同"的標(biāo)記,否則,保存該對(duì)象

    通過(guò)以上的步驟序列化機(jī)制解決了對(duì)象引用的問(wèn)題!

    序列化的實(shí)現(xiàn):

          將需要被序列化的類實(shí)現(xiàn)Serializable接口,該接口沒(méi)有需要實(shí)現(xiàn)的方法,implements Serializable只是為了標(biāo)注該對(duì)象是可被序列化的,然后使用一個(gè)輸出流(如:FileOutputStream)來(lái)構(gòu)造一個(gè)ObjectOutputStream(對(duì)象流)對(duì)象,接著,使用ObjectOutputStream對(duì)象的writeObject(Object obj)方法就可以將參數(shù)為obj的對(duì)象寫(xiě)出(即保存其狀態(tài)),要恢復(fù)的話則用輸入流。

    例子:

    import java.io.*;

    public class Test
    {
        public static void main(String[] args)
        {
            Employee harry = new Employee("Harry Hacker", 50000);
            Manager manager1 = new Manager("Tony Tester", 80000);
            manager1.setSecretary(harry);
           
            Employee[] staff = new Employee[2];
           
            staff[0] = harry;
            staff[1] = manager1;
            try
            {
                ObjectOutputStream out = new ObjectOutputStream(
                    new FileOutputStream("employee.dat"));
                out.writeObject(staff);
                out.close();
               
                ObjectInputStream in = new ObjectInputStream(
                    new FileInputStream("employee.dat"));
                Employee[] newStaff = (Employee[])in.readObject();
                in.close();
      
                /**
                 *通過(guò)harry對(duì)象來(lái)加薪
                 *將在secretary上反映出來(lái)
                 */
                newStaff[0].raiseSalary(10);
               
                for (int i = 0; i < newStaff.length; i++)
                    System.out.println(newStaff[i]);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
       
    }

    class Employee implements Serializable
    {
        public Employee(String n, double s)
        {
            name = n;
            salary = s;
        }
       
        /**
         *加薪水
         */
        public void raiseSalary(double byPercent)
        {
            double raise = salary * byPercent / 100;
            salary += raise;
        }
       
        public String toString()
        {
            return getClass().getName()
                + "[name = "+ name
                + ",salary = "+ salary
                + "]";
        }
       
        private String name;
        private double salary;
    }

    class Manager extends Employee
    {
        public Manager(String n, double s)
        {
            super(n, s);
            secretary = null;
        }
       
        /**
         *設(shè)置秘書(shū)
         */
        public void setSecretary(Employee s)
        {
            secretary = s;
        }
       
        public String toString()
        {
            return super.toString()
                + "[secretary = "+ secretary
                + "]";
        }
       
        //secretary代表秘書(shū)
        private Employee secretary; 
    }

    修改默認(rèn)的序列化機(jī)制:   

          在序列化的過(guò)程中,有些數(shù)據(jù)字段我們不想將其序列化,對(duì)于此類字段我們只需要在定義時(shí)給它加上transient關(guān)鍵字即可,對(duì)于transient字段序列化機(jī)制會(huì)跳過(guò)不會(huì)將其寫(xiě)入文件,當(dāng)然也不可被恢復(fù)。但有時(shí)我們想將某一字段序列化,但它在SDK中的定義卻是不可序列化的類型,這樣的話我們也必須把他標(biāo)注為transient,可是不能寫(xiě)入又怎么恢復(fù)呢?好在序列化機(jī)制為包含這種特殊問(wèn)題的類提供了如下的方法定義:

    private void readObject(ObjectInputStream in) throws

             IOException, ClassNotFoundException;

    private void writeObject(ObjectOutputStream out) throws

             IOException;

    (注:這些方法定義時(shí)必須是私有的,因?yàn)椴恍枰泔@示調(diào)用,序列化機(jī)制會(huì)自動(dòng)調(diào)用的)

    使用以上方法我們可以手動(dòng)對(duì)那些你又想序列化又不可以被序列化的數(shù)據(jù)字段進(jìn)行寫(xiě)出和讀入操作。

          下面是一個(gè)典型的例子,java.awt.geom包中的Point2D.Double類就是不可序列化的,因?yàn)樵擃悰](méi)有實(shí)現(xiàn)Serializable接口,在我的例子中將把它當(dāng)作LabeledPoint類中的一個(gè)數(shù)據(jù)字段,并演示如何將其序列化!

    import java.io.*;
    import java.awt.geom.*;

    public class TransientTest
    {
        public static void main(String[] args)
        {
            LabeledPoint label = new LabeledPoint("Book", 5.00, 5.00);
            try
            {
                System.out.println(label);//寫(xiě)入前
                ObjectOutputStream out = new ObjectOutputStream(new
                    FileOutputStream("Label.txt"));
                out.writeObject(label);
                out.close();
               
                System.out.println(label);//寫(xiě)入后
               
                ObjectInputStream in = new ObjectInputStream(new
                    FileInputStream("Label.txt"));
                LabeledPoint label1 = (LabeledPoint)in.readObject();
                in.close();
                System.out.println(label1);//讀出并加1.0后
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
       
    }

    class LabeledPoint implements Serializable
    {
        public LabeledPoint(String str, double x, double y)
        {
            label = str;
            point = new Point2D.Double(x, y);
        }
       
        private void writeObject(ObjectOutputStream out) throws IOException
        {
            /**
             *必須通過(guò)調(diào)用defaultWriteObject()方法來(lái)寫(xiě)入
             *對(duì)象的描述以及那些可以被序列化的字段
             */
            out.defaultWriteObject();
            out.writeDouble(point.getX());
            out.writeDouble(point.getY());
        }
       
        private void readObject(ObjectInputStream in)
            throws IOException, ClassNotFoundException
        {
            /**
             *必須調(diào)用defaultReadObject()方法
             */
            in.defaultReadObject();
            double x = in.readDouble() + 1.0;
            double y = in.readDouble() + 1.0;
            point = new Point2D.Double(x, y);
        }
       
        public String toString()
        {
            return getClass().getName()
                + "[label = "+ label
                + ", point.getX() = "+ point.getX()
                + ", point.getY() = "+ point.getY()
                + "]";
        }
       
        private  String label;
        transient private Point2D.Double point;
    }

    http://dev.csdn.net/article/31/31306.shtm

    posted on 2005-10-06 00:25 weidagang2046 閱讀(246) 評(píng)論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 日本一区二区在线免费观看| 亚洲国产精品免费视频| 美女视频黄a视频全免费网站一区| 亚洲xxxxxx| 无人视频在线观看免费播放影院| 深夜福利在线视频免费| 国产99视频精品免费专区| 99久久免费中文字幕精品| 在线免费视频一区| 亚洲成a人片在线观看久| 国产亚洲av片在线观看播放| 亚洲色偷偷综合亚洲av78| 极品色天使在线婷婷天堂亚洲| 亚洲精品高清国产麻豆专区| 国产青草视频在线观看免费影院| 免费国产成人高清视频网站| 13小箩利洗澡无码视频网站免费 | 粉色视频成年免费人15次| 波多野结衣亚洲一级| 一级毛片一级毛片免费毛片| 91热久久免费精品99| 国产又黄又爽又猛的免费视频播放 | 亚洲日本国产精华液| 一级成人毛片免费观看| 狼群影院在线观看免费观看直播 | **一级一级毛片免费观看| 日本媚薬痉挛在线观看免费| 亚洲熟妇av一区二区三区下载| 4hu四虎免费影院www| 特级淫片国产免费高清视频| 亚洲精品无码久久久久去q| 视频免费1区二区三区| 啦啦啦中文在线观看电视剧免费版 | 国产桃色在线成免费视频| 亚洲国产精品VA在线观看麻豆 | 美女视频黄频a免费| 免费一级肉体全黄毛片| 亚洲av成人中文无码专区| 成年女人喷潮毛片免费播放| 亚洲一区二区三区乱码在线欧洲| 97av免费视频|