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

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

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

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

    問題的引出:

    如上所述,讀寫對(duì)象會(huì)有什么問題呢?比如:我要將對(duì)象寫入一個(gè)磁盤文件而后再將其讀出來會(huì) 有什么問題嗎?別急,其中一個(gè)最大的問題就是對(duì)象引用!舉個(gè)例子來說:假如我有兩個(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,接下來我們想將它們寫入到磁盤的一個(gè)文件中去,就在寫入文件時(shí)出現(xià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ù)的話,那不是還要搜索它的每一份拷貝來達(dá)到對(duì)象數(shù)據(jù)的一致性,這不是我們所 希望的!

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

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

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

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

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

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

    將 需要被序列化的類實(shí)現(xiàn)Serializable接口,該接口沒有需要實(shí)現(xiàn)的方法,implements Serializable只是為了標(biāo)注該對(duì)象是可被序列化的,然后使用一個(gè)輸出流(如:FileOutputStream)來構(gòu)造一個(gè) ObjectOutputStream(對(duì)象流)對(duì)象,接著,使用ObjectOutputStream對(duì)象的writeObject(Object obj)方法就可以將參數(shù)為obj的對(duì)象寫出(即保存其狀態(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();

    ????????????????????????/**
    ???????????????????????? * 通過harry對(duì)象來加薪 將在secretary上反映出來
    ???????????????????????? */
    ????????????????????????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è)置秘書
    ???????? *
    ???????? */
    ????????public void setSecretary(Employee s)
    ????????{
    ?????????? secretary = s;
    ????????}
    ????????
    ????????public String toString()
    ????????{
    ????????????????return super.toString()+ "[secretary = " + secretary+ "]";
    ????????}

    ????????// secretary代表秘書

    ????????private Employee secretary;

    }

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

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

    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)行寫出和讀入操作。

    下面是一個(gè)典型的例子,java.awt.geom包中的Point2D.Double類就是不可序列化的,因?yàn)樵擃悰]有實(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);// 寫入前
    ????????????????????????ObjectOutputStream out = new ObjectOutputStream(new
    ????????????????????????FileOutputStream("Label.txt"));
    ????????????????????????out.writeObject(label);
    ????????????????????????out.close();
    ????????????????????????System.out.println(label);// 寫入后
    ????????????????????????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
    ????????{
    ????????????????/**
    ???????????????? *
    ???????????????? * 必須通過調(diào)用defaultWriteObject()方法來寫入
    ???????????????? *
    ???????????????? * 對(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;
    }
    posted on 2008-12-05 13:45 無聲 閱讀(237) 評(píng)論(0)  編輯  收藏 所屬分類: 職場(chǎng)生活
    主站蜘蛛池模板: 国产又大又黑又粗免费视频 | 国产成人精品免费视频大全麻豆| 24小时免费看片| 四虎1515hm免费国产| 亚洲精品线在线观看| jzzijzzij在线观看亚洲熟妇| 国偷自产一区二区免费视频| 国产精品黄页在线播放免费| 亚洲Av永久无码精品一区二区| 99热在线观看免费| 亚洲日韩在线观看| 最新亚洲春色Av无码专区| 国产成人无码区免费网站| 免费一级特黄特色大片在线| 亚洲乱码卡三乱码新区| 最新国产乱人伦偷精品免费网站| 情人伊人久久综合亚洲| 一级女性全黄久久生活片免费 | 国产一区二区三区亚洲综合| 亚洲免费闲人蜜桃| 中文字幕亚洲男人的天堂网络| 久久精品无码精品免费专区| 亚洲XX00视频| 亚洲欧美日韩中文高清www777| 永久免费视频网站在线观看| 亚洲AV综合色区无码二区偷拍| 亚洲一区免费观看| 亚洲AV永久无码精品成人| 精品一区二区三区免费观看| 亚洲A∨午夜成人片精品网站| 亚洲成在人线aⅴ免费毛片| 和日本免费不卡在线v| 亚洲欧洲日韩综合| 最近免费中文字幕大全免费| 亚洲AV日韩精品久久久久| 青青操在线免费观看| 国精无码欧精品亚洲一区| 99免费精品视频| 亚洲一区精品视频在线| 亚洲精品无码日韩国产不卡?V| 成人免费视频一区二区|